C++ C++;11可变模板:默认索引数组值
下面是一个简短的程序,使用从和的答案改编的代码打印元组 但是,结果是编译器错误: tmp5.cpp:在函数“void print(const std::tuple&,seq)[with int…S={};T={double,int,char}]中]:C++ C++;11可变模板:默认索引数组值,c++,c++11,tuples,variadic-templates,C++,C++11,Tuples,Variadic Templates,下面是一个简短的程序,使用从和的答案改编的代码打印元组 但是,结果是编译器错误: tmp5.cpp:在函数“void print(const std::tuple&,seq)[with int…S={};T={double,int,char}]中]: tmp5.cpp:23:12:错误:嵌套名称说明符中使用了不完整的类型“std::tuple_size&>” 您知道有什么方法可以提供S..而不使用第二个参数来实现像print这样的函数吗?可能有更好的方法,但我能想到的最简单的方法是添加一个额外的
tmp5.cpp:23:12:错误:嵌套名称说明符中使用了不完整的类型“std::tuple_size&>”
您知道有什么方法可以提供
S..
而不使用第二个参数来实现像print
这样的函数吗?可能有更好的方法,但我能想到的最简单的方法是添加一个额外的间接级别:
#include <iostream>
#include <tuple>
template<int ...>
struct seq { };
template<int N, int ...S>
struct gens : gens<N-1, N-1, S...> { };
template<int ...S>
struct gens<0, S...> {
typedef seq<S...> type;
};
template <typename ...T, int ...S>
void print_impl(const std::tuple<T...> & tup, seq<S...>) {
int res[] = { (std::cout << std::get<S>(tup) << " ", 0)... };
std::cout << std::endl;
}
// Pass args to real implementation here
template <typename ...T>
void print(const std::tuple<T...> & tup)
{
print_impl(tup, typename gens<sizeof...(T)>::type());
}
int main() {
std::tuple<double, int, char> tup(1.5, 100, 'c');
print(tup);
return 0;
}
#包括
#包括
模板
结构序列{};
模板
结构gens:gens{};
模板
结构族{
typedef-seq-type;
};
模板
无效打印(常量标准::元组和元组,顺序){
int res[]={(std::cout问题是,如果不提供第二个函数参数,编译器无法推断索引序列S..
。当它到达默认参数时,它需要知道S..
是什么,因此它无法使用默认参数来确定它
这可以通过提供一个重载print
,用于构建索引列表并转发到接受索引列表的重载来解决:
template <typename ...T>
void print(const std::tuple<T...> & tup) {
print(tup,typename gens<sizeof...(T)>::type());
}
模板
无效打印(常量标准::元组和元组){
打印(tup,typename gens::type());
}
不,没有
事实上,这个问题并不局限于可变模板,它适用于所有模板函数:参数的模板类型不能从其默认值推断
template <typename T>
void func(T = 0) {} // expected-note {candidate template ignored:\
couldn't infer template argument 'T'}
int main() {
func(); // expected-error {no matching function for call to 'func'}
}
模板
void func(T=0){}//预期注释{已忽略候选模板:\
无法推断模板参数“t”}
int main(){
func();//预期错误{调用'func'时没有匹配的函数}
}
你需要换个档位
最简单的方法是提供一个重载,用于传递第二个参数。毕竟,默认参数只是避免编写转发函数的语法糖。我同意,但这与提供打印序列一样困难……我想知道是否有办法提供默认参数对于可变类型?我明白你的意思。但是有没有办法为可变模板指定默认参数?我将制作其中的几个函数,并希望使声明和调用它们尽可能简单…没有语法可以为可变参数提供默认参数。最好提供一个on或重载。铿锵风格的注释真的很无聊。@Johanneschaub litb:我必须承认,我非常喜欢这种显示编译错误的方式(当只有两个错误时…)。我使用的是异构元组(tuple
),其内容都可以发送到模板函数模板数组f(数组)
生成新的元组。我想现在,我将把序列设置为常量表达式,以避免第二个参数中重复的gens
代码。
template <typename ...T>
void print(const std::tuple<T...> & tup) {
print(tup,typename gens<sizeof...(T)>::type());
}
template <typename T>
void func(T = 0) {} // expected-note {candidate template ignored:\
couldn't infer template argument 'T'}
int main() {
func(); // expected-error {no matching function for call to 'func'}
}