Cur*_*ous 5 c++ templates forwarding forwarding-reference c++17
我正在阅读有关类模板的模板参数推导的论文http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0091r3.html。这个功能是 C++17 标准中的,有些事情让我感到困惑。
template <typename T>
class Something {
public:
// delete the copy and move constructors for simplicity
Something(const Something&) = delete;
Something(Something&&) = delete;
explicit Something(T&&) { ... }
explicit Something(const T&) { ... }
template <typename U, typename EnableIfNotT<U, T>* = nullptr>
Something(U&&) { ... }
};
Run Code Online (Sandbox Code Playgroud)
鉴于上面的代码,如果有人尝试像这样实例化上述模板的实例
auto something = Something{std::shared_ptr<int>{}};
Run Code Online (Sandbox Code Playgroud)
右值引用重载总是会被调用吗?由于考虑扣除的过载集是
template <typename T>
Something<T> F(T&&) { ... }
template <typename T>
Something<T> F(const T&) { ... }
template <typename T, typename U, typename EnableIfNotT<U, T>*>
Something<T> F(U&&) { ... }
Run Code Online (Sandbox Code Playgroud)
T
,这是预期的行为吗?
- 第二个重载永远不会优于第一个重载(因为它现在是转发引用重载,而不是右值引用重载),那么这里应该发生什么?
不,这不是转发参考。这是一个关键的区别。来自[temp.deduct.call]:
转发引用是对 cv 不合格模板参数的右值引用,该模板参数不表示类模板的模板参数(在类模板参数推导 ([over.match.class.deduct]) 期间)。
您的候选人是:
template <typename T>
Something<T> F(T&&); // this ONLY matches non-const rvalues
template <typename T>
Something<T> F(const T&); // this matches everything
template <typename T, typename U, typename EnableIfNotT<U, T>*>
Something<T> F(U&&); // this matches nothing
Run Code Online (Sandbox Code Playgroud)
当你写:
auto something = Something{std::shared_ptr<int>{}};
Run Code Online (Sandbox Code Playgroud)
构造函数T&&
是首选,带有T=std::shared_ptr<int>
,因此您最终会得到Something<std::shared_ptr<int>>
类模板专业化。如果改为写:
std::shared_ptr<int> p;
auto something = Something{p};
Run Code Online (Sandbox Code Playgroud)
那么T const&
构造函数是首选(实际上它是唯一可行的候选者)。尽管我们最终都在同一个地方:Something<std::shared_ptr<int>>
。
- 如果不明确指定 T 参数,似乎永远无法调用最后一个,这是预期的行为吗?
正确,T
是非推导的上下文。这是有道理的 - 这个构造函数的存在是为了进行转换,但是您需要指定要转换的内容才能进行转换。让这种“正常工作”对你来说是没有意义的。
- 此外,用户定义的推导指南是否需要位于类定义之后?
是的。按照规则,这就是他们要去的地方。在构造函数中具有尾随返回类型是没有意义的 - 构造函数不会“返回”任何内容。
归档时间: |
|
查看次数: |
284 次 |
最近记录: |