C++ C++;警告:将_U1推断为std::initializer_list<;int>;

C++ C++;警告:将_U1推断为std::initializer_list<;int>;,c++,c++11,C++,C++11,我正在使用g++-4.6.1--std=c++0x并收到一条警告,我似乎无法用这段代码破译: #include <vector> #include <tuple> int main() { std::tuple<std::vector<int>, int> t{ {1, 2, 3}, 10}; } #包括 #包括 int main() { std::元组t{{1,2,3},10}; } 我得到以下警告: scratch.cpp: In

我正在使用
g++-4.6.1--std=c++0x
并收到一条警告,我似乎无法用这段代码破译:

#include <vector>
#include <tuple>

int main()
{
    std::tuple<std::vector<int>, int> t{ {1, 2, 3}, 10};
}
#包括
#包括
int main()
{
std::元组t{{1,2,3},10};
}
我得到以下警告:

scratch.cpp: In function ‘int main()’:
scratch.cpp:6:55: warning: deducing ‘_U1’ as ‘std::initializer_list<int>’ [enabled by default]
/usr/local/include/c++/4.6.1/tuple:329:9: warning:   in call to ‘std::tuple<_T1, _T2>::tuple(_U1&&, _U2&&) [with _U1 = std::initializer_list<int>, _U2 = int, _T1 = std::vector<int>, _T2 = int]’ [enabled by default]
scratch.cpp:6:55: warning:   (you can disable this with -fno-deduce-init-list) [enabled by default]
scratch.cpp:在函数“int main()”中:
scratch.cpp:6:55:警告:将“\u U1”推断为“std::initializer\u list”[默认启用]
/usr/local/include/c++/4.6.1/tuple:329:9:警告:在调用“std::tuple::tuple(_U1&,_U2&&)[带有_U1=std::initializer\u list,_U2=int,_T1=std::vector,_T2=int]”[默认启用]
scratch.cpp:6:55:警告:(您可以使用-fno推断初始列表禁用此功能)[默认情况下启用]
看看实施情况:

template<typename _T1, typename _T2>
class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
    {
      typedef _Tuple_impl<0, _T1, _T2> _Inherited;

    public:
      //...

      template<typename _U1, typename _U2>
        explicit
        tuple(_U1&& __a1, _U2&& __a2)
        : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
    //...
}
模板
类元组:public\u tuple\u impl
{
typedef_Tuple_impl_继承;
公众:
//...
模板
明确的
元组(1&&uua1、2&&ua2)
:_继承的(std::forward(_a1),std::forward(_a2)){}
//...
}
它似乎在抱怨它正在从
初始值设定项列表
(我的代码中的
{1,2,3}
)转发到
std::vector
,这将是
std::tuple
中的第一个类型。我觉得这完全没问题


所以我的问题是:这个警告是什么意思?

这更多的是猜测,而不是引用标准,但我认为它有一定的道理

问题是,用大括号括起来的列表可能意味着很多事情。它可以是一个初始值设定项列表,但根据统一初始化,它也可以是任意数量的其他内容,例如聚合初始值设定项或简单的构造函数参数

考虑以下情况:

struct Bar { Bar(int, int, int){} };

void foo(const std::vector<int> & v);
void zoo(const Bar & v);
这将无法构造第一个元组成员,因为大括号列表推导错误。编写元组的唯一“好”方法是明确地:

std::tuple<Bar, std::vector<int>> s{Bar{1,2,3}, std::vector<int>{1,2,3}};
std::tuple s{Bar{1,2,3},std::vector{1,2,3};

GCC是警告,因为它是一个扩展。我假设这里的警告是一致的,因为它应该算作实现中的诊断。

因此,根据标准,仅大括号参数实际上是无效的?@KerrekSB我实际上不知道确切的答案是什么<代码> STD::tuple < /Cult>有一个非模板构造函数,使用<代码>(t const &…)< />代码,因此,为了回答您的问题,我们必须考虑为什么这个构造函数不应该被选中在模板构造函数上,在哪里发生演绎。我会注意到GCC 4.7(当前开发主干)不给这个代码警告。即使您打开了所有警告和最大限度的严格。考虑到在4.7中(在库和编译器中)对C++0x的支持有了实质性的改进,很可能这是4.6的C++0x支持中的一个错误,或者是标准中的一个后期更改影响了这一领域。
std::tuple<Bar, std::vector<int>> s{Bar{1,2,3}, std::vector<int>{1,2,3}};