У меня есть шаблонный класс, например, так:
struct Base
{
bool operator==(const Base& other) const {
return v == other.v;
}
int v;
};
struct Abc : public Base
{
void execute() { /*logic1*/ }
};
struct Def : public Base
{
void execute() { /*logic2*/ }
};
template <typename T>
class Foo
{
public:
bool operator==(const Foo& other) const {
return (a == other.a) && (b == other.b);
}
int a;
T b;
};
Это прекрасно работает, однако я хотел бы расширить этот метод operator == (), чтобы позволить равенство быть действительным, только если переданный объект имеет тот же тип шаблона. Вот пример:
Foo<Abc> obj1;
Foo<Abc> obj2;
Foo<Def> obj3;
obj1 == obj2; // should be true
obj1 == obj3; // should fail at compile-time or run-time
Когда я делаю это:
bool operator==(const Foo& other) const {
std::cerr << typeid(other).name() << std::endl;
return (a == other.a) && (b == other.b);
}
Я заметил, что экземпляр переданного класса неявно преобразуется в тип этого класса. Я думал о включении переменной-члена в шаблонный объект, чтобы различать их, но немного раздражает необходимость добавлять дополнительную переменную, которая, как мне кажется, не нужна. Есть ли лучший способ выполнить этот тест на равенство?
Как я понимаю, существует неявное преобразование из Foo<T1>
в Foo<T2>
,
Возможные решения:
Запретить неявное преобразование типов (используйте explicit
ключевое слово для конструкторов и операторов приведения).
Делать operator ==
шаблонно и использовать enable_if
разрешить только возможные комбинации:
template <typename T1, typename = std::enable_if<std::is_same<T, T2>::value>::type>
bool operator == (const Foo<T1>& other) const
Других решений пока нет …