2016-12-01 4 views
1

у меня есть, в какой-то момент в моем коде, перегрузка, как этотC++ шаблоны, использование enable_if для двух различных реализации оператора

template<int L> 
template<int M> 
inline StaticMemory<L>& StaticMemory<L>::operator =(const StaticMemory<M>& _m) 
{ 
    if (this != &_m) { //Problem here! 
     set_ui(this->mem, _m.mem, L, M); 
    } 
    return *this; 
} 

Что происходит в том, что проверка я выделил в основном неправильно, потому что когда L != M сравнение указателей не является валидным, если я не брошу его. Возможно, я мог бы наложить указатель, но есть ли способ использовать std::enable_if, чтобы написать две разные версии такого оператора?

Thx

+0

Что вы спрашиваете? Вы спрашиваете, можете ли вы написать одну версию функции, когда 'L == M' и другую версию функции, когда' L! = M'? –

+0

Да, это то, о чем я прошу. – user8469759

+0

Вызов 'M == L' не является тривиальным, поскольку он появляется. Только явный вызов будет делать это: 'l1-> operator = (l2);' иначе назначение копии будет вызовом. – Jarod42

ответ

3

Я думаю, она разрешима без std::enable_if

Просто написать дополнительные operator= так:

template<int L> 
inline StaticMemory<L>& StaticMemory<L>::operator =(const StaticMemory<L>& _m) 
{ 
    if (this != &_m) { //There are no problem here! 
     set_ui(this->mem, _m.mem, L, L); 
    } 
    return *this; 
} 

, который будет работать, если StaticMemory аргумент шаблона является то же самое.

Если они различны, ваш пример кода должен работать, где вы можете бросить все, что вы хотите

Редактировать: доказательство корректности:

#include <iostream> 
template <int I> 
struct Temp { 
    template <int L> 
    void operator=(const Temp<L>&) { 
     std::cout << "Called with L\n"; 
    } 
    void operator=(const Temp<I>&) { 
     std::cout << "Called with I\n"; 
    } 
}; 

int main() { 
    Temp<1> t1; 
    Temp<2> t2; 
    t1 = t1; 
    t1 = t2; 
} 

Выход здесь:

Called with I 
Called with L 
+0

Прошу прощения, у меня есть вопрос, вы предлагаете реализовать оба из них? Разве не было бы конфликтов? потому что когда M = L, который будет генерировать компилятор? – user8469759

+0

@ user8469759 Да, я предлагаю реализовать их оба. Не должно быть конфликтов, и, если M == L, мой шаблон должен быть вызван, если M! = L - ваш. – Starl1ght

+0

@ user8469759 добавлено, доказательства – Starl1ght

1

В качестве назначения копирования не используется

template <int L> 
template <int M> 
Temp<L>& Temp<L>::operator=(const Temp<M>&); 

Назначение Копирование только

template <int L> 
Temp<L>& Temp<L>::operator=(const Temp<L>&); 

И да так, вы должны написать как перегруженных в вашем случае.

Путь назвать назначение шаблона (первая перегрузка) с таким же типом является вызов явно, что-то вроде:

this->operator=<L>(rhs);