3

考虑一个小的独立用例,其中我想确定一个类型是完整的还是不完整的

#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.1and它会--std=c++11产生编译错误

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();

我在这里想念什么?有什么可能的解决方法?

4

2 回答 2

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真实的特征。sizeofT

请注意这一点,因为与大多数功能不同,类型的完整性可能会在编译单元之间甚至在同一单元的不同位置发生变化。当类型在程序中的不同位置发生变化时,C++ 不喜欢它。some_template<some_args...>

活生生的例子

于 2017-03-02T13:49:32.387 回答
0

由于如果 T 不可调用,则 C++14 result_of::type 不存在。

在您的情况下, struct FooIncomplete 没有什么可调用的。

于 2017-03-02T11:24:14.027 回答