2016-10-10 4 views
2

私は、値に起こっていることを簡単に見ることができるように、基本的に他のタイプのラッパーであるテンプレートクラスを作成しようとしています任意の演算子、コンストラクタ、デストラクタなどが呼び出されます。 私は演算子bool()は、オペレータbool()を持つ任意のクラスのoperator_bool()を呼び出すことによって動作するようにしようとしています。誰かがboolに変換しようとすると、どちらもできないクラスはコンパイルに失敗するだけです。私はこの単純なケースで困惑しているので、まだこの部分に集中していません。クロスプラットフォームのクラステンプレートパラメータによるオーバーロードの選択

これはMSVC 2015でコンパイルされて正常に動作しますが、Clang(3.8.1)またはGCC(6.2)のどちらでもコンパイルできません。両打ち鳴らすとgcc

#include <type_traits> 
#include <utility> 
#include <assert.h> 

template <typename T> 
struct Wrapper { 
    T val; 

    template<typename...Params> 
    Wrapper(Params&&...args): val(std::forward<Params>(args)...){} 

    /** 
    * \brief bool conversion operator 
    */ 
    template <typename = std::enable_if_t<std::is_fundamental<T>::value>> 
    operator bool() const { 
     return static_cast<bool>(val); 
    } 

    /** 
    * \brief bool conversion operator 
    */ 
    template <typename = std::enable_if_t<!std::is_fundamental<T>::value>, typename = void> 
    operator bool() const { 
     return val.operator bool(); 
    } 
}; 


struct HasOperatorBool { 
    mutable bool done{ false }; 

    operator bool() const{ 
     done = true; 
     return done; 
    } 
}; 

int main(int argc, char** argv) { 
    Wrapper<HasOperatorBool> whob; 
    bool didIt = whob; 
    assert(didIt); 

    Wrapper<int> wi{1}; 
    bool bi = wi; 
    assert(bi); 

    return 0; 
} 

:これは、問題を示してストリップダウンバージョンであるhttps://godbolt.org/g/v3B6TE

:GCCとクランは、両方のGCCとクラン上のエラーを示すオンラインコンパイラに-std=c++1z

リンクに設定されていますおよそstd::enable_if_tは一切typeを持っていない何かを言っている:

GCC:

In file included from /tmp/gcc-explorer-compiler116910-70-16kehep/example.cpp:1: 
/usr/lib/gcc/x86_64-linux-gnu/5.4.1/../../../../include/c++/5.4.1/type_traits:2388:44: error: no type named 'type' in 'std::enable_if<false, void>'; 'enable_if' cannot be used to disable this declaration 
using enable_if_t = typename enable_if<_Cond, _Tp>::type; 
^~~~~ 
15 : note: in instantiation of template type alias 'enable_if_t' requested here 
template <typename = std::enable_if_t<std::is_fundamental<T>::value>> 
^ 
40 : note: in instantiation of template class 'Wrapper<HasOperatorBool>' requested here 
Wrapper<HasOperatorBool> whob; 
^ 
In file included from /tmp/gcc-explorer-compiler116910-70-16kehep/example.cpp:1: 
/usr/lib/gcc/x86_64-linux-gnu/5.4.1/../../../../include/c++/5.4.1/type_traits:2388:44: error: no type named 'type' in 'std::enable_if<false, void>'; 'enable_if' cannot be used to disable this declaration 
using enable_if_t = typename enable_if<_Cond, _Tp>::type; 
^~~~~ 
2 errors generated. 
Compiler exited with result code 1 

打ち鳴らす:

In file included from /tmp/gcc-explorer-compiler116910-70-1nlkefa/example.cpp:1:0: 
/opt/gcc-explorer/gcc-6.2.0/include/c++/6.2.0/type_traits: In substitution of 'template<bool _Cond, class _Tp> using enable_if_t = typename std::enable_if::type [with bool _Cond = std::is_fundamental<HasOperatorBool>::value; _Tp = void]': 
16 : required from 'struct Wrapper<HasOperatorBool>' 
40 : required from here 
/opt/gcc-explorer/gcc-6.2.0/include/c++/6.2.0/type_traits:2512:61: error: no type named 'type' in 'struct std::enable_if<false, void>' 
using enable_if_t = typename enable_if<_Cond, _Tp>::type; 

私はこれに代わるアプローチで多分興味がありますが、私は、これは3つのコンパイラの2で動作しませんなぜ技術的な理由で非常に興味があります。 1つ以上のコンパイラが間違っていますか?私が望むものを達成する方法はありますか?

答えて

2

あなたは実際にSFINAEをやっていません。 std::enable_if<T>を使用する場合、問題のTは、コンパイラがインスタンス化しようとしているテンプレート(immediate-context)から直接取得する必要があります。しかしTクラスのテンプレートパラメータであり、メソッドではなく、置換が失敗し、SFINAEの代わりにハードエラーが発生します。 VSの動作がその点で標準に準拠しているかどうかはわかりません。

/** 
* \brief bool conversion operator 
*/ 
template <typename X = T, typename = std::enable_if_t<std::is_fundamental<X>::value>> 
operator bool() const { 
    return static_cast<bool>(val); 
} 

/** 
* \brief bool conversion operator 
*/ 
template <typename X = T, typename = std::enable_if_t<!std::is_fundamental<X>::value>, typename = void> 
operator bool() const { 
    return val.operator bool(); 
} 
+1

、優秀な答えをありがとう!あなたの代わりに欲しい

はクラステンプレートパラメータにデフォルトはダミーテンプレートパラメータを導入することですコンパイル時にコンパイラエクスプローラのページの色が点灯する方法はとてもエキサイティングです! –

+0

もちろん、インテリセンスではまだ動作しませんが、それほど問題ではありません:P(Intellisenseはあいまいだと思っています) –

関連する問題