我正在阅读有关类模板模板参数推导的论文,链接地址 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&&) { ... }
};
鉴于上述代码,如果有人尝试像这样实例化上述模板的一个实例:
auto something = Something{std::shared_ptr<int>{}};
右值引用重载总是会被调用吗?由于用于推导的重载集合是
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&&) { ... }
- 第二个重载将永远不会优先于第一个重载被调用(因为它现在是一个转发引用重载,而不是右值引用重载),那么这里应该发生什么?
- 而且似乎最后一个重载如果没有明确指定
T
参数就无法被调用,这是预期的行为吗? - 此外,在使用类模板的模板参数推断时,是否还有其他需要注意的地方或样式准则?
- 另外,用户定义的推导指南是否必须在类定义之后?例如,可以在类定义本身中的构造函数声明中使用尾返回类型(与迭代器构造函数不同,请参见http://en.cppreference.com/w/cpp/language/class_template_deduction)?
std::enable_if_t<!std::is_same<U,T>::value>
)。 - Henri Menke