【问题标题】:Is 'deep' template argument deduction posible?“深度”模板参数推导可行吗?
【发布时间】:2019-10-19 22:53:18
【问题描述】:

关键是,我有模板函数,我想用它作为回调:

template <class ...Ind>
void fill_given_rows(mat& matrix, Ind ...ind){

它从这样的类成员函数中调用:

template<typename F, class ... Args>
void pic::modify(F func, Args ... args){
  func(matrix, args...);
}

哪一个按顺序从 main 调用为:

matrix.modify(fill_given_rows, 0, 2, 3);

gcc 给了我这样的输出:

50:41: error: no matching function for call to 'pic::modify(<unresolved overloaded function type>, int, int, int)'
50:41: note: candidate is:
27:8: note: template<class F, class ... Args> void pic::modify(F, Args ...)
27:8: note:   template argument deduction/substitution failed:
50:41: note:   couldn't deduce template parameter 'F'

这里是完整版代码:

#include <vector>
#include <array>
#include <initializer_list>
#include <type_traits>

typedef std::vector<std::vector<int>> mat;

template <class ...Ind>
void fill_given_rows(mat& matrix, Ind ...ind){
  std::array<std::common_type_t<Ind...>, sizeof...(Ind)> lines = {{ind...}};
  int height = matrix.size();
  int width = matrix[0].size();

  for(auto row: lines){
    for(int y=0; y<width; y++){
        matrix[row][y]=1;
    }
  }
}

class pic{
public:
  pic(int width, int height); //generate empty matrix

  //callback for all matrix modification 
  template<typename F, class ... Args>
  void modify(F, Args ...); 

private:
  mat matrix;
};

pic::pic(int width, int height){
  matrix.resize(height);
  for(auto& row: matrix){
    row.resize(width);
  }
}

template<typename F, class ... Args>
void pic::modify(F func, Args ... args){
  func(matrix, args...);
}


int main() {
  int width=10, height=5;
  pic matrix(width, height);

  matrix.modify(fill_given_rows, 0, 2, 3);

  return 0;
}

为什么它不起作用?

【问题讨论】:

  • 请提供minimal reproducible example。关于 stackoverflow 的问题必须是自包含的。链接将来可能会中断,然后这个问题就毫无价值了。
  • 无法推断出F的类型。你需要matrix.modify(fill_given_rows&lt;int, int, int&gt;, 0, 2, 3);

标签: c++ templates variadic-templates template-argument-deduction


【解决方案1】:

如果您使用函数而不是函数模板,也许可以?

有点像

struct foo
 {
   template <typename ... Ind>
   void operator() (mat & matrix, Ind ...ind) {
      std::array<std::common_type_t<Ind...>, sizeof...(Ind)> lines = {{ind...}};
      int height = matrix.size();
      int width = matrix[0].size();

      for(auto row: lines){
         for(int y=0; y<width; y++){
            matrix[row][y]=1;
         }
      }
   }
 };

// ...

foo f;

matrix.modify(f, 0, 2, 3);

你的代码有问题

// ...........vvvvvvvvvvvvvvv  template function              
matrix.modify(fill_given_rows, 0, 2, 3);

函数模板不是一个对象,而是一组对象。

而且您不能将一组对象作为函数的参数传递。

您可以从集合中选择正确的对象,说明模板类型

// ...........vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv  now is a single object              
matrix.modify(fill_given_rows<int, int, int>, 0, 2, 3);

但是(恕我直言)这有点不舒服。

传递一个函数(使用模板operator())你传递一个“包含”函数模板的对象。

【讨论】:

  • @ThomasSablik - 不幸的是,我比英语更懂 C++ :(。谢谢。已更正。
猜你喜欢
  • 1970-01-01
  • 2013-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-26
相关资源
最近更新 更多