【问题标题】:type inference with rvalue initializer_list使用右值 initializer_list 进行类型推断
【发布时间】:2013-07-05 20:14:43
【问题描述】:

在下面的代码中

#include <initializer_list>
#include <utility>

template<typename T> void f(T&& x) {}
template<typename T> void g(std::initializer_list<T> x) {}

int main()
{
    auto   x = {0}; // OK
    auto&& y = {0}; // OK
    g(x); // OK
    g(std::move(x)); // OK
    g({0}); // OK
    f(x); // OK
    f(std::move(x)); // OK
    f({0}); // failure
    return 0;
}

右值initializer_list可以用auto推导,但不能用template推导。

为什么 C++ 禁止这样做?

【问题讨论】:

  • 可能是因为{0} 被视为一种“文字初始化器”,直观上您不能从文字中移动(或者对可以移动的右值引用)。
  • 顺便说一句,你错过了#include &lt;utility&gt;
  • @chris - 你是对的。我会编辑
  • this question 中询问了委员会为何做出这种改变。

标签: c++ c++11


【解决方案1】:

我相信这是由于 14.8.2.1/1:

[...] 初始化列表参数导致参数被视为非推导上下文 (14.8.2.5)。 [例子: [...]

template<class T> void g(T);
g({1,2,3});                    // error: no argument deduced for T

——结束示例]

现在你可能认为auto 只是模板参数推导,但是对于大括号列表auto 在7.1.6.4/6 中得到特殊处理:

将出现的auto 替换为新发明的类型模板参数U,或者如果初始值设定项是braced-init-list (8.5.4),则替换为std::initializer_list&lt;U&gt;。 [...] [示例

auto x1 = { 1, 2 };   // decltype(x1) is std::initializer_list<int>

——结束示例]

【讨论】:

  • 肯定有什么怪事让委员会只对汽车给予特殊待遇
  • @a.lasram:我想允许auto x = { 1, 2, 3 }; 并没有什么坏处,所以你不妨拥有它。另一方面,允许模板参数推导可能会受到伤害(我正在考虑构造函数)。
猜你喜欢
  • 2014-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-13
  • 2022-11-07
  • 2015-08-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多