匿名临时对象和 class 模板参数推导 - gcc vs clang
Anonymous temporaries and class template argument deduction - gcc vs clang
考虑以下代码片段:
template <typename T>
struct foo
{
foo(T) { }
};
int main()
{
foo{0};
}
g++ 7愉快地创建了一个foo
类型的临时对象,推导T = int
.
clang++ 5和6拒绝编译代码:
error: expected unqualified-id
foo{0};
^
这是一个 clang 错误,还是标准中有什么东西阻止 class 模板参数推导 为未命名的临时对象启动?
Clang 错误 (#34091)
A placeholder for a deduced class type can also be used in [...] or as the simple-type-specifier in an explicit type conversion (functional notation). A placeholder for a deduced class type shall not appear in any other context.
[ Example:
template<class T> struct container {
container(T t) {}
template<class Iter> container(Iter beg, Iter end);
};
template<class Iter>
container(Iter b, Iter e) -> container<typename std::iterator_traits<Iter>::value_type>;
std::vector<double> v = { /* ... */ };
container c(7); // OK, deduces int for T
auto d = container(v.begin(), v.end()); // OK, deduces double for T
container e{5, 6}; // error, int is not an iterator
— end example ]
考虑以下代码片段:
template <typename T>
struct foo
{
foo(T) { }
};
int main()
{
foo{0};
}
g++ 7愉快地创建了一个foo
类型的临时对象,推导T = int
.
clang++ 5和6拒绝编译代码:
error: expected unqualified-id foo{0}; ^
这是一个 clang 错误,还是标准中有什么东西阻止 class 模板参数推导 为未命名的临时对象启动?
Clang 错误 (#34091)
A placeholder for a deduced class type can also be used in [...] or as the simple-type-specifier in an explicit type conversion (functional notation). A placeholder for a deduced class type shall not appear in any other context. [ Example:
template<class T> struct container { container(T t) {} template<class Iter> container(Iter beg, Iter end); }; template<class Iter> container(Iter b, Iter e) -> container<typename std::iterator_traits<Iter>::value_type>; std::vector<double> v = { /* ... */ }; container c(7); // OK, deduces int for T auto d = container(v.begin(), v.end()); // OK, deduces double for T container e{5, 6}; // error, int is not an iterator
— end example ]