2012-05-30 52 views
3

我有一个可变模板函数f。编译没有问题(使用g++ -std=c++11和可能使用c++0x):为什么我不能手动提供模板参数?

#include <tuple> 

template<int ...> 
struct seq { }; 

template <typename ...T, int ...S> 
void f(std::tuple<T...> arg, seq<S...> s) { 
    // ... do stuff 
} 

int main() { 
    f<int>(std::tuple<int>(10), seq<0>()); 
    return 0; 
} 

编译器会自动在工作中int ...S罢了。

不过,我似乎无法手动提供的整数参数:

int main() { 
    f<int, 0>(std::tuple<int>(10), seq<0>()); 
    return 0; 
} 

输出:

/tmp/t.cpp: In function ‘int main()’: /tmp/t.cpp:12:42: error: no
matching function for call to ‘f(std::tuple, seq<0>)’
/tmp/t.cpp:12:42: note: candidate is: /tmp/t.cpp:7:6: note:
template void f(std::tuple<_TElements ...>,
seq) /tmp/t.cpp:7:6: note: template argument
deduction/substitution failed:

我相信我读过,技术上也应该只有一个可变参数提供给模板函数的模板参数包(在第一种情况下,它完全由上下文确定),以便解释它(?)。

对于调试,有没有办法在GCC输出用于...Sstderrstdout的扩展?当它们一开始不编译时,调试这样的东西会非常有用。

+0

什么编译器的版本?它对代码说什么? –

+0

gcc 4.7。它说它无法确定模板类型。 – user

+0

请复制并粘贴_actual_错误。 – ildjarn

回答

4

我不知道手动指定两个模板参数包的方法。由于模板包可能包含任意多的参数,因此编译器无法知道什么时候你的意思是第一个停止和第二个启动。自动或部分自动扣除似乎工作,但是,我不知道这是否只是一些慷慨的g ++ ...

我不知道你实际上想要做什么,但我敢打赌,你不同时需要两个模板包。您可能会引入一个间接层,例如,

template <typename ... Tuple_Elements> 
void do_something_with_single_value(std::tuple<Tuple_Elements...> arg, int s) { 
    // ... do stuff 
} 

template <typename Tuple_Type, int ...S> 
void f(Tuple_Type arg, seq<S...> s) { 
    // ... do stuff which needs all S at the same time 
    // ... call do_something_with_single_value in compile time loop to access tuple elements 
} 

也许你的签名是你的函数有太多的责任的提示。尝试创建具有明确责任的较小功能。

有一种方法可以输出为T和S推导的参数,但前提是编译器可以确定匹配。对于这一点,你需要在编译时引发的错误:

template <typename ...T, int ...S> 
void f(std::tuple<T...> arg, seq<S...> s) { 
static_assert(std::tuple_size<std::tuple<T...>>::value < 0, "Provoked error message"); 
    // ... do stuff 
} 

这将产生以下输出在你的工作例如:

stack.cpp: In function ‘void f(std::tuple<_Elements ...>, seq<S ...>) [with T = {int}, int ...S = {0}]’: 
stack.cpp:15:34: instantiated from here 
stack.cpp:10:2: error: static assertion failed: "Provoked error message" 
相关问题