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:在函数“int main()”中:/tmp/t.cpp:12:42:错误:没有
匹配函数调用“f(std::tuple, seq<0>)”< br> /tmp/t.cpp:12:42: 注意:候选是:/tmp/t.cpp:7:6: 注意:
模板 void f(std::tuple<_TElements ...>,
seq) /tmp /t.cpp:7:6:注意:模板参数
扣除/替换失败:

我相信我已经阅读过,从技术上讲,应该只为模板函数提供一个可变参数模板参数包(在第一种情况下,它完全由上下文决定),所以这就解释了(?)。

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

4

1 回答 1

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"
于 2013-01-03T11:46:20.460 回答