2017-06-21 23 views
1

私のクラスmytypeがCスタイルの配列かC++のSTL配列を使用するかどうかをコンパイル時に選択できるようにするために、テンプレートクラスのテンプレート等価演算子がコンパイルされない

#include<array> 
#include<cassert> 

template<bool IsTrue, typename IfTrue, typename IfFalse> 
struct choose; 

template<typename IfTrue, typename IfFalse> 
struct choose<true, IfTrue, IfFalse> { 
    typedef IfTrue type; 
}; 

template<typename IfTrue, typename IfFalse> 
struct choose<false, IfTrue, IfFalse> { 
    typedef IfFalse type; 
}; 

template<bool ArrayIsRaw> 
struct mytype { 
    typedef typename choose<ArrayIsRaw, int[50], std::array<int, 50>>::type array_t; 
    array_t data{}; 
}; 

int main() { 
    mytype<true> raw_version; 
    mytype<false> stl_version; 
    raw_version.data[5] = 15; 
    stl_version.data[15] = 5; 
    raw_version.data[10] = stl_version.data[15]; 
    assert(raw_version.data[10] == 5); 
    return 0; 
} 

これはうまくいきます。しかし、基本的には、raw_version == stl_versionを有効でコンパイル可能なコードにして、各要素が同一であればtrueを返すようにしたいという等価演算子をこのクラスに追加したいと考えています。

しかし、私は私のクラス定義に次のコードを追加するとき:

template<bool Raw1, bool Raw2> 
friend bool operator==(mytype<Raw1> const& a, mytype<Raw2> const& b) { 
    for(size_t i = 0; i < 50; i++) if(a.data[i] != b.data[i]) return false; 
    return true; 
} 

私は次のエラーを取得する:

prog.cpp: In instantiation of ‘struct mytype<false>’: 
prog.cpp:32:16: required from here 
prog.cpp:24:14: error: redefinition of ‘template<bool Raw1, bool Raw2> bool operator==(const mytype<Raw1>&, const mytype<Raw2>&)’ 
    friend bool operator==(mytype<Raw1> const& a, mytype<Raw2> const& b) { 
       ^~~~~~~~ 
prog.cpp:24:14: note: ‘template<bool Raw1, bool Raw2> bool operator==(const mytype<Raw1>&, const mytype<Raw2>&)’ previously defined here 

私はこのエラーを修正するために何が必要ですか?

答えて

2

operator==の両方の引数をテンプレート化すると、mytype<true>mytype<false>の正確な関数テンプレートが再定義されます。単純にこの作品を作るための最初の(または第二の、両方ではない)の引数からテンプレートを削除:

template<bool Raw2>  
friend bool operator==(mytype const& a, mytype<Raw2> const& b) {  
    // ... 
} 

また、あなたのchoosestd::conditionalだけの実装であり、あなたが代わりに

using array_t = typename std::conditional<ArrayIsRaw, int[50], std::array<int, 50>>::type; 
を持つことができると思わ

またはC++の場合14

using array_t = std::conditional_t<ArrayIsRaw, int[50], std::array<int, 50>>; 
関連する問題