2017-12-22 7 views
2

クラスにはpushの2つの異なる実装があり、ブール値のテンプレート引数に基づいて選択します。そのように、this answerで説明したように、私はSFINAE原理を使用してみました:booleanテンプレートパラメータを使用してメンバ関数を有効にするにはどうすればよいですか?

template<class T, bool foo=true> 
class Bar { 
    template <> 
    typename std::enable_if<foo>::type 
    push(const T& value) { /* one implementation */} 

    template <> 
    typename std::enable_if<!foo>::type 
    push(const T& value) { /* another implementation */ } 
} 

しかし、私はgccの下の「クラススコープ内の関数pushを特化することはできません」のエラーを取得しています、と私はその理由を理解していません。私のコードは、リンクされた答えのそれとまったく同じではありませんが、非常によく似ていると私は重要な違いを見つけることができません。

私もthis answerで提案されているものに似た構文を使用してみましたが、それはまた、動作しない(エラーではなく、「クラスのメンバは、再宣言することはできません」さ):

template <bool enable=foo> 
    typename std::enable_if<enable>::type 
    push(const T& value) { /* one implementation */} 

    template <bool enable=!foo> 
    typename std::enable_if<enable>::type 
    push(const T& value) { /* another implementation */ } 

は、どのように私はこれを達成することができますか?

答えて

2

まず、SFINAEは、関数テンプレートのオーバーロードで機能します。だから、2番目のアプローチにしてください。しかし、同じシグネチャで2つのオーバーロードを宣言します。テンプレートパラメータのデフォルト引数は署名に属していないことに注意してください。

代替として

template <bool enable=foo> 
typename std::enable_if<enable>::type 
//      ~~~~~~ 
push(const T& value) { /* one implementation */} 

template <bool enable=foo> 
typename std::enable_if<!enable>::type 
//      ~~~~~~~ 
push(const T& value) { /* another implementation */ } 
+0

うわー、それは完全に機能します。ありがとうございました。 –

2

に変更し、それを:C++ 17で

  • if constexpr

    template<class T, bool foo=true> 
    class Bar { 
    public: 
        void push(const T& value) { 
         if constexpr(foo) { 
          /* one implementation */ 
         } else { 
          /* another implementation */ 
         } 
        } 
    }; 
    
  • タグディスパッチ:

    template<class T, bool foo=true> 
    class Bar { 
        void push_impl(const T& value, std::true_type) { 
         /* one implementation */ 
        } 
        void push_impl(const T& value, std::false_type) { 
         /* another implementation */ 
        } 
    
    public: 
        void push(const T& value) { 
         push_impl(value, std::integral_constant<bool, foo>{}); 
        } 
    }; 
    
+0

素晴らしいです。代わりのオプションをありがとう。私はある時点でこれらが役に立つと確信しています。 –

関連する問題