【发布时间】:2018-09-20 23:34:21
【问题描述】:
这是我对 is_copy_assignable 实现的尝试:
template<typename, typename = void>
struct IsCopyAssignable : std::false_type
{};
template<typename T>
struct IsCopyAssignable<T, decltype(std::add_lvalue_reference<T>::type = std::add_lvalue_reference<const T>::type, void())> : std::true_type
{};
这是一个失败。
这是测试用例:
int main()
{
struct Structure {};
std::cout << "IsCopyAssignable=\n";
std::cout << IsCopyAssignable<int>::value << '\n'; // should be true
std::cout << IsCopyAssignable<int&>::value << '\n'; // should be true
std::cout << IsCopyAssignable<const int&>::value << '\n'; // should be false
std::cout << IsCopyAssignable<const double&>::value << '\n'; // should be false
std::cout << IsCopyAssignable<class Structure>::value << '\n'; // should be true
std::cout << '\n';
}
它们都打印错误。
(然后我意识到 declval 与方便的 void_t - 当然还有 decltype - 可以用于类似的事情。)但我仍然不明白为什么这个不起作用。我想我们想测试是否可以将const T& 分配给T&(就像复制分配运算符一样)。那么,为什么呢?
【问题讨论】:
-
int& = const int&没有任何意义。可能你想把std::declval<typename std::add_lvalue_reference<T>::type>()等放在那里。 -
@DanielSchepler 这就是答案。基本上,您注意到的是,专业化总是 SFINAE 消失,因为它没有意义。
-
从技术上讲,如果您进行了诸如
template<> struct std::add_lvalue_reference<Structure> { static bool type; };之类的专业化处理,您也许可以使IsCopyAssignable<Structure>::value为真,std::add_lvalue_reference<const Structure>也同样如此 - 尽管标准自然也会使这种未定义的行为...跨度>
标签: c++ templates template-meta-programming sfinae copy-assignment