2017-06-21 70 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) {  
    // ... 
} 

还显示出你的choose只是std::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>>;