ple*_*ndo 13 c++ gcc language-lawyer template-argument-deduction c++17
请考虑以下代码
struct A {
A(int id) : id_ { id } {}
A(const A& rhs) { std::cout << "cctor from " +
std::to_string(rhs.id_) << std::endl; }
A(A&& rhs) { std::cout << "mctor from " +
std::to_string(rhs.id_) << std::endl; }
int id_;
};
template<typename T>
struct B1 {
constexpr B1(T&& x) noexcept : x_ { std::forward<T>(x) } {}
T x_;
};
template<typename T>
struct B2 {
constexpr B2(T&& x) noexcept;
T x_;
};
template<typename T>
constexpr
B2<T>::B2(
T&& x
) noexcept :
x_ { std::forward<T>(x) } {
}
int
main(
) {
A a { 1 };
//B1 b11 { a }; // Not compiling
B1 b12 { A { 2 } };
B2 b21 { a };
B2 b22 { A { 3 } };
return 0;
}
Run Code Online (Sandbox Code Playgroud)
产量
mctor from 2
mctor from 3
Run Code Online (Sandbox Code Playgroud)
所以它看起来好像外部定义的构造函数完全转发其参数的值类别,而内联定义的构造函数则不然.
是否将外部定义的构造函数处理为函数模板(完全转发其参数)或此处发生了什么?
欢迎链接到标准的相应部分.
我正在使用GCC 7.2.0.
看起来GCC错误地将T&&
自动生成的演绎指南视为转发参考:
template <typename T>
B2(T&& x) -> B2<T>;
Run Code Online (Sandbox Code Playgroud)
在这种情况下T&&
是非转发r值引用,因为它是一个类参数.相反,GCC错误地推断出T=A&
参数类型和B2<T>=B2<A&>
类类型,这会折叠构造函数中的引用类型,允许代码使用左值构造函数参数进行编译:
constexpr B2(A& x) noexcept;
Run Code Online (Sandbox Code Playgroud)
类模板参数推导不区分内联和外联定义.在这种特殊情况下,B2 b21 { a };
应该失败.
归档时间: |
|
查看次数: |
1279 次 |
最近记录: |