C++ 为什么';我的模板不接受初始值设定项列表吗

C++ 为什么';我的模板不接受初始值设定项列表吗,c++,c++11,initializer-list,C++,C++11,Initializer List,我创建了一个模板,如下所示 template<typename T> void f(T const& t) { } 但GCC的行为似乎不符合标准 m.cpp: In function 'int main()': m.cpp:6:25: warning: deducing 'const T' as 'const std::initializer_list<int>' m.cpp:4:6: warning: in call to 'void f(const T&

我创建了一个模板,如下所示

template<typename T>
void f(T const& t) { }
但GCC的行为似乎不符合标准

m.cpp: In function 'int main()':
m.cpp:6:25: warning: deducing 'const T' as 'const std::initializer_list<int>'
m.cpp:4:6: warning:   in call to 'void f(const T&) [with T = std::initializer_list<int>]'
m.cpp:6:25: warning:   (you can disable this with -fno-deduce-init-list)
m.cpp:在函数“int main()”中:
m、 cpp:6:25:警告:将“const T”推断为“const std::initializer\u list”
m、 cpp:4:6:警告:在调用“void f(const T&)[with T=std::initializer\u list]时”
m、 cpp:6:25:警告:(您可以使用-fno推断初始列表禁用此选项)
有人能解释一下我如何在没有警告的情况下完成这项工作吗?谢谢

是这样说的

之所以存在此选项,是因为此推断是对C++0x工作草案中当前规范的扩展,并且存在一些关于潜在过载解决问题的担忧

这些信息可能只是过时了(根据消息来源,上次更新是在2008年)。据我所知,该扣减被纳入GCC,但我希望该标准的后续草案将删除该规则,或至少限制该规则

有人能解释一下我如何在没有警告的情况下完成这项工作吗

我不知道
这个
是否引用了您引用的确切代码,或者您是否只想知道如何使用初始值设定项列表实例化函数模板而不触发警告,但是如果是后者,如果问题仅仅是推断正确的类型,您可以通过调用

f<initializer_list<int>>({1, 2, 3});
f({1,2,3});
这并不漂亮,但它可以避免警告,而不必修改编译器命令行参数

我可能会在附近放一条评论,解释说由于某些GCC版本的缺陷,您不依赖编译器推断正确的类型。

像{1,2,3}这样的“东西”不符合表达式的条件。它没有类型。因此,不进行类型推断。但是C++0x对“auto”做了一个显式的例外,所以

auto x = {1,2,3};
实际有效,decltype(x)将是
初始值设定项\u列表
。但这是一条只适用于汽车的特殊规则。我猜他们想做这样的循环

for (int x : {2,3,5,7,11}) {
   ...
}
由于这种循环利用了特殊的规则,所以无法正常工作

至于解决问题,您可以添加一个
初始值设定项\u list
重载作为“包装器”:

模板
内联无效外部(初始值设定项\u列表il){
内耳;
}

我没有对此进行测试,但我目前的理解是它应该可以工作。

Hmm似乎很不幸,因此认为
初始值设定项列表
标记与
初始值设定项列表
-.-C++0x将落泪!AFAICS,它不是同义词。是否有一些内置逻辑可以用
x-y
替换
x\u y
?哦,没关系,我刚刚看到我将只使用std::initializer\u列表在7.1.6.4“auto”说明符[dcl.spec.auto]
C++0x中提到的特殊规则对“auto”做了一个明确的例外
是的,在您所展示的类似赋值的语法中,还有
autosomething{a,b,c}
表单。后者一直是后遗症中的一个不一致的痛点,现在只能用C++17来修复,其中
autosomething{blah}
没有
=
符号意味着“创建一个
decltype(blah)
”的对象,从
blah
初始化-不是当前意义上的“创建一个
initializer\u list
称为
something
,其中一个元素的类型与
blah
相同”。最后但到目前为止,这意味着要对受影响的代码库进行大量更新C
for (int x : {2,3,5,7,11}) {
   ...
}
template<class T>
inline void outer(initializer_list<T> il) {
   inner(il);
}