【问题标题】:gcc 6.1 std::result_of compilation errorgcc 6.1 std::result_of 编译错误
【发布时间】:2017-03-02 08:03:19
【问题描述】:

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

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

我在这里缺少什么?有什么可能的解决方法?

【问题讨论】:

  • 看起来像 g++ 回归
  • @Arunmu 那么 g++ 应该选择operator()(...) 吗?它试图复制一个不完整的类型
  • 您是否尝试过不使用匿名namespace,即使用命名的。
  • 您是否考虑过当两个FooIncomplete 在一个上下文中完成但在另一个上下文中不完整时会发生什么(根据标准),并且都尝试了您的技巧?我不认为结果是……好。
  • 可能的解决方法是 SFINAE 探测 FooIncomplete::~FooIncomplete 的存在。见How to detect existence of a class using SFINAE?

标签: c++ c++11 gcc result-of gcc6


【解决方案1】:

从 C++14 开始,如果 T 不可调用,则 result_of::type 不存在。

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

【讨论】:

  • OP 尝试调用foo::operator(),而不是FooIncomplete
【解决方案2】:

使用类似 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 >;

如果我们可以将sizeof 应用于T,我们得到一个特征is_complete

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

Live example.

【讨论】:

    猜你喜欢
    • 2017-06-27
    • 2016-11-13
    • 1970-01-01
    • 2012-06-11
    • 2016-10-13
    • 1970-01-01
    • 2013-09-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多