首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么`initializer_list<pair>`和`initializer_list<tuple>`的行为不同?

为什么`initializer_list<pair>`和`initializer_list<tuple>`的行为不同?
EN

Stack Overflow用户
提问于 2016-04-07 12:49:36
回答 1查看 1.4K关注 0票数 15

以下代码编译并运行:

代码语言:javascript
复制
#include <initializer_list>
#include <iostream>
#include <vector>
#include <tuple>

void ext( std::initializer_list<std::pair<double, std::vector<double> >> myList )
{
    //Do something
}

///////////////////////////////////////////////////////////

int main(void) {
    ext( { {1.0, {2.0, 3.0, 4.0} } } );
    return 0;
}

而这一条没有:

代码语言:javascript
复制
#include <initializer_list>
#include <iostream>
#include <vector>
#include <tuple>

void ext( std::initializer_list<std::tuple<double, std::vector<double> >> myList )
{
    //Do something
}

///////////////////////////////////////////////////////////

int main(void) {
    ext( { {1.0, {2.0, 3.0, 4.0} } } );
    return 0;
}

唯一的区别是,在第一种情况下,ext()函数接受一个类型为initializer_list<pair> (works)的参数,而另一个则使用initializer_list<tuple> (不工作)。然而,cplusplus.com states that

对是元组的一种特殊情况。

那么,为什么一个代码工作,而另一个代码不工作呢?

更多信息

在第二种情况下,clang++输出的错误是:

代码语言:javascript
复制
main.cpp:33:2: error: no matching function for call to 'ext'
      ext( { {1.0, {2.0, 3.0, 4.0} } } );
      ^~~
main.cpp:7:6: note: candidate function not viable: cannot convert initializer list argument to 'std::tuple<double,
      std::vector<double, std::allocator<double> > >'
void ext( std::initializer_list<std::tuple<double, std::vector<double> >> myList )
      ^
1 error generated.

而g++输出:

代码语言:javascript
复制
main.cpp: In function ‘int main()’:
main.cpp:33:35: error: converting to ‘std::tuple<double, std::vector<double, std::allocator<double> > >’ from initializer list would use explicit constructor ‘constexpr std::tuple<_T1, _T2>::tuple(const _T1&, const _T2&) [with _T1 = double; _T2 = std::vector<double>]’
  ext( { {1.0, {2.0, 3.0, 4.0} } } );
                                   ^
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-04-07 12:59:25

cplusplus.com不是一个很好的站点,因为它充满了错误的语句,比如“对是元组的一个特殊情况”。你可以用cppreference代替。事实上,对并不是元组的特殊情况。

现在人们认为tuple是更好的设计;pair的历史要大得多,而且由于向后兼容性,现在不能更改。

错误消息表明,区别在于tuple有一个explicit构造函数,但pair没有。

这意味着在构建元组时需要提到类名:

代码语言:javascript
复制
 ext( { std::tuple<double,std::vector<double>>{1.0, {2.0, 3.0, 4.0} } } );

这将在C++17中更改:tuple的构造函数将是显式的当且仅当元组的类型之一是具有显式构造函数的类类型。gcc 6已经实现了这一功能。(信贷-乔纳森·韦克利)请参阅N4387

票数 15
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36476719

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档