检查成员函数时 SFINAE 测试失败
SFINAE-test fails when checking for member function
我尝试实现自己的 SFINAE 测试以确定模板变量的类型,在本例中是标量还是向量:
#include <iostream>
#include <vector>
template <typename...>
using void_t = void;
template <typename, template <typename> class, typename = void_t<>>
struct detect : std::false_type {};
template <typename T, template <typename> class Op>
struct detect<T, Op, void_t<Op<T>>> : std::true_type {};
template <typename T>
using toSize_t = decltype(std::declval<T>().size());
template <typename T>
using has_toSize = detect<T, toSize_t>;
int main(void)
{
std::cout << "Hello World\n";
std::vector<int> vec_a;
std::vector<double> vec_b;
double scal_a;
int scal_b;
std::cout << "scal_b is a vector: " << detect<int, has_toSize>{} << '\n';
return 0;
}
现在,int
肯定没有成员函数 size()
,但我仍然得到一个 true
而不是 false
值。为什么?
表达式:
detect<int, has_toSize>{}
很奇怪。
注意,has_toSize
是别名。编写 has_toSize<T>
始终是一个有效的表达式,其中 T
是任意类型。结果 detect
检测到 Op<T>
,其中 Op
是 has_toSize
,是一个有效的表达式。所以,输出是 true
.
detect
的正确使用方法是:
std::cout << has_toSize<int>{} << std::endl;
^^^^^
check type
这意味着,您检查一个类型(int
在这种特殊情况下)是否具有 size()
成员函数。
在 C++17 中,您可以使用 is_detected
。这将所有 SFINAE 隐藏在一个漂亮的元函数中。调用类似于其他答案。
#include <experimental/type_traits>
template < typename T >
using toSize_t = decltype(std::declval<T>().size());
template < typename T >
using has_toSize = std::experimental::is_detected< toSize_t, T >;
int main()
{
static_assert( has_toSize<int>::value == false );
}
我尝试实现自己的 SFINAE 测试以确定模板变量的类型,在本例中是标量还是向量:
#include <iostream>
#include <vector>
template <typename...>
using void_t = void;
template <typename, template <typename> class, typename = void_t<>>
struct detect : std::false_type {};
template <typename T, template <typename> class Op>
struct detect<T, Op, void_t<Op<T>>> : std::true_type {};
template <typename T>
using toSize_t = decltype(std::declval<T>().size());
template <typename T>
using has_toSize = detect<T, toSize_t>;
int main(void)
{
std::cout << "Hello World\n";
std::vector<int> vec_a;
std::vector<double> vec_b;
double scal_a;
int scal_b;
std::cout << "scal_b is a vector: " << detect<int, has_toSize>{} << '\n';
return 0;
}
现在,int
肯定没有成员函数 size()
,但我仍然得到一个 true
而不是 false
值。为什么?
表达式:
detect<int, has_toSize>{}
很奇怪。
注意,has_toSize
是别名。编写 has_toSize<T>
始终是一个有效的表达式,其中 T
是任意类型。结果 detect
检测到 Op<T>
,其中 Op
是 has_toSize
,是一个有效的表达式。所以,输出是 true
.
detect
的正确使用方法是:
std::cout << has_toSize<int>{} << std::endl;
^^^^^
check type
这意味着,您检查一个类型(int
在这种特殊情况下)是否具有 size()
成员函数。
在 C++17 中,您可以使用 is_detected
。这将所有 SFINAE 隐藏在一个漂亮的元函数中。调用类似于其他答案。
#include <experimental/type_traits>
template < typename T >
using toSize_t = decltype(std::declval<T>().size());
template < typename T >
using has_toSize = std::experimental::is_detected< toSize_t, T >;
int main()
{
static_assert( has_toSize<int>::value == false );
}