将向量传递给可变参数模板

时间:2016-02-17 16:08:32

标签: c++ c++11

我有一个使用Variadic模板编码的数字方法。我想传递一个参数混合,一些类型为double,一些类型为vector。最小的例子;

template<typename... Ts>
using custom_function_t = double(*) (double, Ts...);

template<typename... Ts> 
double BiPart(double min, double max,custom_function_t<Ts...> f,Ts... args)
double FunctionA(double A, double a, double b, vector<double> &C);
int main()
{
    double a=0, b=1,x=0, y=1;
    vector<double> C;
    BiPart(x,y,FunctionA, a,b, &C);
    return(0);
}

double FunctionA(double A, double a, double b, vector<double> &C)
{
some stuff here
}

我收到错误: '没有匹配功能可以调用'Bipart(...)'' '模板参数教育/替换失败:与'std :: vector&amp;'不一致的参数包教育和'std :: vector''。

2 个答案:

答案 0 :(得分:0)

很奇怪,我从gcc得到的完整错误(当我从C前面删除&符号时)是:

balls.cpp: In function ‘int main()’:
balls.cpp:15:34: error: no matching function for call to ‘BiPart(double&, double&, double (&)(double, double, double, std::vector<double>&), double&, double&, std::vector<double>&)’
     BiPart(x,y,FunctionA, a,b, C);
                              ^
balls.cpp:15:34: note: candidate is:
balls.cpp:9:8: note: template<class ... Ts> double BiPart(double, double, custom_function_t<Ts ...>, Ts ...)
 double BiPart(double min, double max,custom_function_t<Ts...> f,Ts... args);
        ^
balls.cpp:9:8: note:   template argument deduction/substitution failed:
balls.cpp:15:34: note:   inconsistent parameter pack deduction with ‘std::vector<double>&’ and ‘std::vector<double>’
     BiPart(x,y,FunctionA, a,b, C);
                              ^

所以它明确表示它正在尝试将vector<double>&与另一个vector<double>&匹配,但稍后在错误消息中忘记它正在处理引用。编译器错误可能吗?或者只是c ++是c ++。

我知道这不能回答你的问题,但是如果你只想借用BiPart中的向量,你可以将它作为vector<double>*(而不是引用)传递它,它会起作用。如果您想将数据移动到BiPart调用而不复制它,您可以将函数参数设为vector<double>&&,然后使用move(C)调用BiPart。这也是编译。

答案 1 :(得分:0)

你可能实际上正在调用这样的函数:

BiPart(x,y,FunctionA, a,b, C);

而不是你帖子中指向矢量的指针,对吗?

如果是这样,错误消息实际上非常具有描述性。发生的事情是这样的:您传入的最后一个参数C,在类型推导中使用两次,一次用于参数f,一次用于参数args }。在第一种情况下,由于FunctionA的声明方式,其类型推断为std::vector<double>&。在第二种情况下,它被推断为简单的std::vector<double>,没有参考。因为在这两个地方你都使用了相同的模板参数Ts...,所以这些参数必须完全匹配。

要解决此问题,您可以从不同角度解决问题:

您可以修改FunctionA以按值而不是引用取最后一个参数。这将解决它,因为这次推断的类型将匹配(两者都将推断为std::vector<double>)。

您还可以通过为这两个函数使用不同的参数类型名来取消链接两个推断类型,以便它们不必匹配:

template<typename... Ts, typename... OtherTs> 
double BiPart(double min, double max, custom_function_t<Ts...> f, OtherTs&&... args);

注意两个模板参数。在这种情况下,为参数f推导出的类型(最后仍为std::vector<double>&)不必完全匹配BiPartstd::vector<double>的其余参数推导出的类型。 {1}}为最后一个)。