【问题标题】:Why can't I manually provide the template arguments?为什么我不能手动提供模板参数?
【发布时间】:2012-06-05 04:35:44
【问题描述】:

我有一个可变参数模板函数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)’的匹配函数
/tmp/t.cpp:12:42: 注意: 候选是: /tmp/t.cpp:7:6: 注意:
模板 void f(std::tuple<_telements ...>,
seq) /tmp/t.cpp:7:6: 注意:模板参数
扣减/代换失败:

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

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

【问题讨论】:

  • 什么版本的编译器?代码说明了什么?
  • gcc 4.7。它说它无法确定模板类型。
  • 请复制并粘贴实际错误。
  • FTR,-std=c++0x 和 -std=c++11 是一回事。提供前者是为了向后兼容以前版本的编译器。
  • 当错误提示它无法确定模板类型时,它永远不会扩展模板 - 能够看到扩展将无济于事。

标签: c++ gcc c++11 variadic-templates


【解决方案1】:

我无法手动指定两个模板参数包。由于模板包可能包含任意多个参数,因此编译器无法知道您的意思是第一个停止和第二个开始的时间。不过,自动或部分自动扣除似乎可行,但我不确定这是否只是 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"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-25
    • 2016-11-19
    • 1970-01-01
    相关资源
    最近更新 更多