使用模板元编程,可以查询类型的属性。例如,在下面的情况下,我正在检查某种类型是否具有成员函数“ foo”,该成员函数将另一种类型用作参数。
是否有一种方法可以检查参数类型是否与模板相对应,而不是要转换为模板的参数,例如可以将double或char转换为float(使main两次输出true),但是我试图查看是否存在一种结构my_test_t
以便与之完美匹配,即main()
除非为T2 = float
,否则打印为false。
struct S2
{
int foo(float x)
{
return 0;
}
};
template <typename T1, typename T2>
using my_test_t = decltype(declval<T1>().foo(declval<T2>()));
template <typename T1, typename T2, typename = void>
struct is_formed : std::false_type
{
};
template <typename T1, typename T2>
struct is_formed<T1, T2, void_t<my_test_t<T1, T2>>> : std::true_type
{
};
int main()
{
cout << boolalpha << is_formed<S2, double>::value << endl;
cout << boolalpha << is_formed<S2, char>::value << endl;
}
您可以尝试使用std :: is_same来匹配foos参数的确切类型,首先,您必须在结构中定义要比较的类型。
可能会有更好的方法,我不会马上就知道。
#include <type_traits>
#include <utility>
template <typename C, typename P>
auto test(short) -> std::false_type;
template <typename C, typename P>
auto test(int)
-> decltype(static_cast<decltype(std::declval<C&>().foo(std::declval<P>())) (C::*)(P)>(&C::foo)
, std::true_type{});
template <typename C, typename P>
using my_test_t = decltype(test<C, P>(0));
你快到了。我更改了测试,以便使用foo
的地址,并通过将static_cast
指向其自身来测试所得成员指针的类型。
#include <type_traits>
#include <iostream>
using namespace std;
struct S2
{
int foo(float x)
{
return 0;
}
};
template <typename T1, typename T2>
using my_test_t = decltype( static_cast<int(T1::*)(T2)>(&T1::foo) );
template <typename T1, typename T2, typename = void>
struct is_formed : std::false_type
{ };
template <typename T1, typename T2>
struct is_formed<T1, T2, void_t< my_test_t<T1,T2> >> : std::true_type
{ };
int main()
{
cout << boolalpha << is_formed<S2, float>::value << endl; // true
cout << boolalpha << is_formed<S2, double>::value << endl; // false
cout << boolalpha << is_formed<S2, char>::value << endl; // false
}
(以上代码使用C ++ 17编译,因为C ++ 14中没有std :: void_t-您需要编写自己的代码。)