考虑一个小的独立用例,其中我想确定一个类型是完整的还是不完整的
#include <type_traits>
namespace {
struct foo {
template<class T, std::size_t = sizeof(T)>
std::false_type operator()(T&);
std::true_type operator()(...);
};
struct FooIncomplete;
}
int main() {
std::result_of<foo(FooIncomplete&)>::type();
return 0;
}
使用带有gcc 4.9.3
标记的--std=c++11
可以很好地编译。但是,对于gcc 6.1
和--std=c++11
,它会生成compilation error
main.cpp: In function 'int main()':
main.cpp:17:5: error: 'type' is not a member of 'std::result_of<{anonymous}::foo({anonymous}::FooIncomplete&)>'
std::result_of<foo(FooIncomplete&)>::type();
我在这里缺少什么?可能有什么可行的工作?
答案 0 :(得分:0)
如果T不可调用,因为C ++ 14 result_of :: type不存在。
在你的情况下,结构FooIncomplete无需调用。
答案 1 :(得分:0)
使用类似C ++ 20的is_detected
:
namespace details {
template<template<class...>class Z, class, class...Ts>
struct can_apply:std::false_type{};
template<class...>struct voider{using type=void;};
template<class...Ts>using void_t = typename voider<Ts...>::type;
template<template<class...>class Z, class...Ts>
struct can_apply<Z, void_t<Z<Ts...>>, Ts...>:std::true_type{};
}
template<template<class...>class Z, class...Ts>
using can_apply=typename details::can_apply<Z,void,Ts...>::type;
template<class T>
using size_of = std::integral_constant<std::size_t, sizeof(T)>;
template<class T>
using is_complete = can_apply< size_of, T >;
如果我们可以将is_complete
应用于sizeof
,我们会得到一个特征T
。
要小心这一点,因为与大多数功能不同,类型的完整性可以在编译单元之间甚至在同一单元中的不同位置处改变。当类型some_template<some_args...>
在程序中的不同位置发生更改时,C ++不会喜欢。