2017-03-02 62 views
3

考慮一個小的獨立的用例,其中我想確定一個類型是完全或不完全使用GCC 6.1的std ::的result_of編譯錯誤

#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

看起來像一個g ++迴歸 – Arunmu

+0

@Arunmu應該g ++選擇'運算符()(...)'然後呢?它試圖製作一個不完整類型的副本 –

+0

您是否嘗試過沒有匿名'namespace',即使用一個命名空間來代替。 – user3405291

回答

0

因爲如果T不可調用,C++ 14 result_of :: type不存在。

在你的情況struct FooIncomplete沒有什麼要調用。

+0

OP嘗試調用'foo :: operator()',而不是'FooIncomplete' –

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...>在程序中的不同位置發生變化時。

Live example