【问题标题】:Passing Vectors to a Variadic Template将向量传递给可变参数模板
【发布时间】:2016-02-17 16:08:31
【问题描述】:

我有一个使用可变参数模板编码的数值方法。我想将混合参数传递给它,一些双精度类型和一些向量类型。最小的例子;

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&' 和 'std::vector' 不一致。

【问题讨论】:

  • 你确定你正在编译 this 程序吗?它有几个拼写错误,导致编译错误与您所询问的不同。

标签: c++ c++11


【解决方案1】:

奇怪的是,我从 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&lt;double&gt;&amp; 与另一个vector&lt;double&gt;&amp; 匹配,但稍后在错误消息中忘记它正在处理引用。编译器错误可能吗?或者只是 c++ 是 c++。

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

【讨论】:

  • 我们对“清楚地”有两种不同的定义... ;)
  • 在这种情况下,我只需要将存储在向量中的数据获取到 BiPart 中进行一些计算,我不关心在 BiPart 中对其进行修改,因此我将使用 vector* 选项并进行测试它。谢谢。
【解决方案2】:

您可能实际上是这样调用该函数的:

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

而不是像您的帖子中那样使用指向向量的指针,对吗?

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

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

您可以修改FunctionA 以通过值而不是通过引用来获取最后一个参数。这将解决它,因为这一次推导的类型都将匹配(都将推导为 std::vector&lt;double&gt;)。

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

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

注意两个模板参数。在这种情况下,为参数f(最后一个仍为std::vector&lt;double&gt;&amp;)推导的类型不必完全匹配为BiPart(最后一个为std::vector&lt;double&gt;)的其余参数推导的类型。

【讨论】:

  • 你必须使用OtherTs&amp;&amp;... args,否则你仍然通过副本。
猜你喜欢
  • 2019-03-27
  • 2014-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-10
  • 2011-03-16
  • 2011-11-15
相关资源
最近更新 更多