简体   繁体   中英

Templated Equality Operator for Template Class Does Not Compile

I've written the following code intended to allow my class, mytype , to select at compile-time whether to use a C-style array or a C++ STL array, like so:

#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;
}

This works just fine. However, I want to add an equality operator to this class that is agnostic of the underlying types involved: basically, I want raw_version == stl_version to be valid, compileable code which will return true if each element is identical.

But when I add the following code to my class definition:

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;
}

I get the following error:

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

What do I need to do to fix this error?

By making both arguments to operator== templated, you are redefining this exact function template for mytype<true> and mytype<false> . Simply remove the templating from the first (or second, but not both) argument to make this work:

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

It also appears that your choose is just an implementation of std::conditional and you could instead have

using array_t = typename std::conditional<ArrayIsRaw, int[50], std::array<int, 50>>::type;

or for c++14

using array_t = std::conditional_t<ArrayIsRaw, int[50], std::array<int, 50>>;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM