为什么我不能手动提供模板参数? [英] Why can't I manually provide the template arguments?

查看:113
本文介绍了为什么我不能手动提供模板参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个可变参数模板功能f.编译良好(使用g++ -std=c++11并可能使用c++0x):

I have a variadic template function f. This compiles fine (using g++ -std=c++11 and possibly using 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.

The compiler automatically fills in the int ...S that works.

但是,我似乎无法手动提供整数参数:

However, I can't seem to manually provide the integer arguments:

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>)"的匹配函数
/tmp/t.cpp:12:42:注意:候选者是:/tmp/t.cpp:7:6:注意:
模板void f(std :: tuple< _TElements ...>,
seq)/tmp/t.cpp:7:6:注意:模板参数
扣除/替代失败:

/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:

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

I believe I've read that technically there should only be one variadic template parameter pack provided to a template function (and in the first case, it is completely determined by context), so that explains it(?).

对于调试,GCC中是否有一种方法可以将用于...S的扩展输出到stderrstdout?当它们最初不编译时,对于调试像这样的东西将是非常有用的.

For debugging, is there a way in GCC to output the expansion used for ...S to stderr or stdout? It would be very useful for debugging things like this when they don't compile at first.

推荐答案

我不知道手动指定两个模板参数包的方法.由于模板包可能包含任意多个参数,因此编译器无法知道何时要停止第一个,而要停止第二个.虽然自动或部分自动推论似乎可行,但我不确定这是否只是g ++的一些慷慨...

I know no way to specify two template argument packs manually. Since a template pack may contain arbitrarily many arguments, there is no way for the compiler to know when you meant the first one to stop and the second one to start. Automatic or partially automatic deduction seems to work, though, but I am not sure if this is just some generousity of g++...

我不确定您实际上要做什么,但是我敢打赌您不需要同时使用两个模板包.您可能会引入一层间接,例如

I am not sure what you are actually trying to do, but I bet that you do not need both template packs at the same time. You might introduce one layer of indirection, e.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
}

也许您的签名暗示您的功能职责过多.尝试创建职责明确的较小功能.

Perhaps your signature is a hint that your function has too many responsibilities. Try to create smaller functions with clear responsibilities.

只有在编译器可以确定匹配的情况下,才可以输出为T和S推导的参数的方法.为此,您需要在编译时引发错误:

There is a way to output the arguments deduced for T and S, but only if the compiler can determine a match. For this, you would need to provoke an error at compile time:

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
}

这将在您的工作示例中生成以下输出:

This would generate the following output in your working example:

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"

这篇关于为什么我不能手动提供模板参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆