'deep' 模板参数推导是否可行?
Is 'deep' template argument deduction posible?
关键是,我有模板函数,我想用它作为回调:
template <class ...Ind>
void fill_given_rows(mat& matrix, Ind ...ind){
它从这样的 class 成员函数调用:
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;
}
为什么不起作用?
也许如果您使用函数模板而不是函数模板?
类似于
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);
函数模板不是一个对象而是一组对象。
并且您不能将一组对象作为函数的参数传递。
您可以 select 正确的对象,从集合中解释模板类型
// ...........vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv now is a single object
matrix.modify(fill_given_rows<int, int, int>, 0, 2, 3);
但是(恕我直言)这有点不舒服。
传递一个函数式(使用模板 operator()
)你传递一个对象,"contains" 一个函数模板。
关键是,我有模板函数,我想用它作为回调:
template <class ...Ind>
void fill_given_rows(mat& matrix, Ind ...ind){
它从这样的 class 成员函数调用:
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;
}
为什么不起作用?
也许如果您使用函数模板而不是函数模板?
类似于
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);
函数模板不是一个对象而是一组对象。
并且您不能将一组对象作为函数的参数传递。
您可以 select 正确的对象,从集合中解释模板类型
// ...........vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv now is a single object
matrix.modify(fill_given_rows<int, int, int>, 0, 2, 3);
但是(恕我直言)这有点不舒服。
传递一个函数式(使用模板 operator()
)你传递一个对象,"contains" 一个函数模板。