我试图使用一些可变参数模板参数但我很快被一个我无法理解的错误所阻止 .
#include <tuple>
template <typename T>
struct Foo
{
typedef T type;
};
// return a tuple of pair of args and Foo templated on Types
template <typename Head, typename ...Args, typename Type, typename ...Types>
auto func(Head arg, Args... args)
{
return std::tuple_cat(std::make_tuple(std::make_pair(arg, Foo<Type>())),
func<Args..., Types...>(args...));
}
template <typename Head, typename Type>
auto func(Head arg)
{
return std::make_tuple(std::make_pair(arg, Foo<Type>()));
}
int main()
{
func<int, bool, char>(1, 2, 3);
}
这里func尝试解压缩模板参数,并在第二个可变参数模板上创建一对func参数和Foo结构的元组,但我有:
test.cc:25:3: error: no matching function for call to 'func'
func<int, bool, char>(1, 2, 3);
^~~~~~~~~~~~~~~~~~~~~
test.cc:11:6: note: candidate template ignored: couldn't infer template argument 'Type'
auto func(Head arg, Args... args)
^
test.cc:18:6: note: candidate function template not viable: requires single argument 'arg', but 3
arguments were provided
auto func(Head arg)
^
1 error generated.
为什么不能推断出类型? (gcc告诉我同样的事)
我确信在执行std :: tuple_cat实现(https://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-api-4.5/a01066_source.html)之后可以使用多个可变参数模板,我认为这是一个简单的示例,如果有解决方案或标准不接受,我应该更清楚我 .
谢谢你的帮助,
2 回答
最后推断出推论的论点 .
...
模板参数是贪婪的 - 它们将消耗在参数中传递,并且对于以后的模板参数不会"save" .完成后,从非模板函数参数中进行推导 .
像这样交换:
另外,摆脱了其他的重载,所以
func<int,int>(3)
并不含糊 .这会使递归中断,但这很容易修复:
其中有好的和短的奖金 .
这里的关键数据点是可变参数将与空列表匹配 . 这有几个后果 .
第一个结果是给出以下模板声明:
以及以下实例:
实例化可以通过多种方式匹配模板:
1 .
2 .
所以,这是歧义的一个来源 .
main()
中的引用可以匹配任一模板定义 . 尽管存在各种神秘的规则,在某些情况下可以解决这种模糊性,但最好不依赖于神秘的模板消歧规则,或者至少采用几种标准的基本方法 .但是,回到主题,关键是编译器将在这里落后于八球,没有一个明确的候选者来解决
main()
中的模板引用 . 但它变得更糟 . 特定和
因为,variatic参数(在本例中为
Args...
)可以再次匹配空列表,例如:可以匹配任一功能签名 .
将所有这些因素结合在一起,编译器无法真正在这里做出正面或反面 .