Modern Effective C++这本书上讲到:
template<class T> void f(T t){} int main(){ f({1,2,3}); }
这样的代码是编译不过的,原因是模板参数T在模板实例化的时候必须是已知类型,而{1,2,3}是个braced-init-list,
除非本人先auto x={1,2,3};用auto来把x推导成std::initializer_list,然后传给f就行了。
这个本人都能理解。
问题:
为什么后面又说auto在推导返回值的时候,不能return一个braced-init-list?
例如
auto f() { return {1,2,3}; }
就会有编译错误,这是C++14规定的。本人不清楚为什么要编译不过呢,既然赋值语句auto x={1,2,3}都能把braced-init-list推导成std::initializer_list,auto用作返回值的时候就不行了?
书上还有一个例子说:
auto resetV=[&v](const auto& newValue){v=new Value;}
这个newValue前面的auto也不能接受{1,2,3}。同样原因,为什么要有这样的限制?
—
是不是从设计的角度说,假如返回值auto可以接受braced-init-list的话,会导致某些二义性什么的?
还请大牛指点。
解决方案
5
原因是 initializer_list 用于表达式中的。
15
用 braced-init-list 初始化 std::initializer_list 的过程可以描述为先用这个 braced-init-list 初始化一个数组(用户代码无法直接使用这个数组),再让 std::initializer_list 指向这个数组。假如返回 braced-init-list ,那个数组会立即在函数返回时被析构,被返回的 std::initializer_list 无法被有效地使用吧
20
An object of type std::initializer_list<E> is constructed from an initializer list as if the implementation allocated a temporary array of N elements of type const E, where N is the number of elements in the initializer list. Each element of that array is copy-initialized with the corresponding element of the initializer list, and the std::initializer_list<E> object is constructed to refer to that array.