c++ - 使用右值 initializer_list 进行类型推断

标签 c++ c++11

在下面的代码中

#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++ 禁止这样做?

最佳答案

我相信这是由于 14.8.2.1/1 造成的:

[...] an initializer list argument causes the parameter to be considered a non-deduced context (14.8.2.5). [Example: [...]

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

end example]

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

replacing the occurrences of auto with either a new invented type template parameter U or, if the initializer is a braced-init-list (8.5.4), with std::initializer_list<U>. [...] [Example:

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

end example]

关于c++ - 使用右值 initializer_list 进行类型推断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17496268/

相关文章:

c++11 - 使用与 typedef - 是否存在微妙的、鲜为人知的区别?

c++ - 如何在 Windows CE Direct-X 应用程序中显示(打印机)对话框?

c++ - 一个基类只有一个派生类可以吗?

c++ - 当我在 on_read 上看到错误时,我应该清理 bread::flat_buffer 吗?

c++ - 如何在 C++ 正则表达式中捕获 0-2 组并打印它们?

C++ 无法用 {...} 初始化

c++ - 宏重载

c++ - 编辑 QTableWidgetItem 时捕获 ESC 键

c++ - 以通用方式选择有效的随机枚举值

c++ - cocos2dx v3.7 如何防止反弹?