在C ++标准§13.3.1.7[over.match.list]中,陈述如下: 在复制列表初始化中,如果selectexplicit构造函数,则初始化是不合格的。 这就是我们无法做到的原因,例如: struct foo { // explicit because it can be called with one argument explicit foo(std::string s, int x = 0); private: // … }; void f(foo x); f({ "answer", 42 }); (请注意,这里发生的不是一个转换 ,即使构造函数是“隐式的”也不会是一个,这是直接使用构造函数初始化一个foo对象,除了std::string ,没有转换这里。) 这对我来说似乎很好。 没有办法,隐式转换会咬我。 如果{ "answer", 42 }可以初始化别的东西,编译器就不会背叛我,做错了事情: struct bar { // explicit because it can be called with […]
今天在我的项目中遇到一个内存问题,用一个使用c ++ 11 initializer_list的类。 系统发出内存问题:dbgdel.cpp中的expression式_BLOCK_TYPE_IS_VALID(pHead-> nBlockUse)我把代码简化为一个简单的例子,它不再抛出一个expression式,但是从debugging输出中问题变得明显。代码是正确的,也似乎与g ++的工作。 #include <functional> #include <memory> #include <string> #include <iostream> #include <vector> #include <map> #include <sstream> #include <initializer_list> using namespace std; class B { public: char data[256]; B(const string& x) { cout << "Init " << this << endl; } B(const B& b) { cout << "Copy " << this […]
在另一个话题中 ,@Dietmar给出了这个解决scheme: template <typename… T> std::tuple<T…> parse(std::istream& in) { return std::tuple<T…>{ T(in)… }; } 说明, 使用大括号初始化工作是因为大括号初始化符列表中的参数的评估 顺序是它们出现的顺序 。 (强调我的) C ++标准(n3485)的相关文本是, 在braced-init-list的初始化程序列表中,初始化程序子句(包括从程序包扩展(14.5.3)产生的任何子程序子句)按其出现的顺序进行评估。 也就是说,与给定初始化子句相关联的每个值计算和副作用在与初始值设定项列表的逗号分隔列表中的任何初始化子句相关联的每个值计算和副作用之前被sorting。 [注意:不pipe初始化的语义如何,这个评估顺序都是成立的。 例如,当初始化列表的元素被解释为构造函数调用的参数时,即使通常对调用的参数没有sorting约束,也适用。 – 注意] 所以我试图用下面的代码来testing它: template<int N> struct A { std::string data; A(std::istream & stream) { stream >> data; } friend std::ostream& operator<<(std::ostream & out, A<N> const & a) { return out […]