简体   繁体   English

转发初始化列表表达式

[英]Forwarding initializer list expressions

Initializer list expressions are really convenient for initializing C++ containers: 初始化列表表达式非常便于初始化C ++容器:

std::vector<int>({1, 2, 3})

...but it seems that a brace-enclosed initializer list expression, like {1,2,3} will only bind to a function that takes a std::initializer_list<int> - it doesn't seem to bind to a universal (forwarding) reference : ...但似乎括号括起的初始化列表表达式,如{1,2,3} 只会绑定到一个带有std::initializer_list<int>的函数 - 它似乎没有绑定到通用(转发)参考

template <class T>
void foo(T&& v)
{
  std::vector<int>(std::forward<T>(v));
}

int main()
{
  foo({1, 2, 3})
}

This outputs: 这输出:

test2.cpp:11:6: note: template<class U> void foo(U&&)
test2.cpp:11:6: note:   template argument deduction/substitution failed:
test2.cpp:33:13: note:   couldn't deduce template parameter ‘U’

(This was the result with GCC 4.7.2.) (这是GCC 4.7.2的结果。)

This unfortunately means we can't forward an initializer list expression. 遗憾的是,这意味着我们无法转发初始化列表表达式。 Since it would be very convenient to do that, I'd like to ask why is it that this doesn't work? 既然这样做很方便,我想问为什么这不起作用? Why can't a brace enclosed initializer list expression bind to a forwarding reference? 为什么括号封闭的初始化列表表达式不能绑定到转发引用? Or is this allowed, and perhaps my compiler is just too old? 或者这是允许的,也许我的编译器太老了?

It's not that it can't bind to the parameter of your function; 并不是它不能绑定到你的函数的参数; it's just that the compiler is unable to detect the type of your template. 只是编译器无法检测模板的类型。 This compiles: 这编译:

#include <vector>

template <class T>
void foo(T&& v)
{
  std::vector<int>(std::forward<T>(v));
}

int main()
{
  foo(std::initializer_list<int>{1, 2, 3});
}

The initializer list cannot be deduced in this case. 在这种情况下,无法推断初始化列表。 This is actually covered explicitly by the standard in [temp.deduct.call]: 这实际上由[temp.deduct.call]中的标准明确涵盖:

Template argument deduction is done by comparing each function template parameter type (call it P ) with the type of the corresponding argument of the call (call it A ) as described below. 模板参数推导是通过将每个函数模板参数类型(称为P )与调用的相应参数的类型(称为A )进行比较来完成的,如下所述。 If P is a dependent type, [...]. 如果P是依赖类型,[...]。 Otherwise, an initializer list argument causes the parameter to be considered a non-deduced context (14.8.2.5). 否则,初始化列表参数会将参数视为非推导上下文(14.8.2.5)。 [ Example: [例如:

 template<class T> void f(std::initializer_list<T>); f({1,2,3}); // T deduced to int f({1,"asdf"}); // error: T deduced to both int and const char* template<class T> void g(T); g({1,2,3}); // error: no argument deduced for T 

The example here for g is exactly your case - T is not a dependent type, so this is considered to be a non-deduced context. 这里g的例子就是你的情况T不是一个依赖类型,所以这被认为是一个非推导的上下文。 The compiler is correct to reject your code. 编译器拒绝您的代码是正确的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM