2014-01-18 2 views
0

У меня есть вопрос о явных и шаблонах:используя явный с шаблонами C++

template<class T> 
class A { 

    class A_Impl { 
     T var; 

     public: 
      explicit A_Impl(T var1) : var(var1), version(1) 
      { 
      } 

      A_Impl(const A_Impl& a) : var(a.var), version(1) 
      { 
      } 

      const A_Impl& operator=(const A_Impl& a) 
      { 
       var=a.var;++version;return *this; 
      } 

      operator T() const { return var; } 

      friend class A<T>; 
    }; 

    A_Impl a; 

public: 
    A(T var): a(var) 
    { 
    } 

    A_Impl& get() { return a; } 
}; 

void main() { 
    A<int> a1(5); 
    cout<<"a1 = "<<a1.get()<<endl; 

    a1.get()=7; 
    cout<<"a1 = "<<a1.get()<<endl; 

    a1=13; 
    cout<<"a1 = "<<a1.get()<<endl; 
} 

я получаю ан ошибки в a1.get()=7; который говорит ни один оператор «=» не соответствует этим операндам

Кроме того, если я беру явное слово, оно будет скомпилировано, но я не понимаю разницу между функцией a1.get() и a1=13;, которая отлично работает даже с явным.

+0

http://stackoverflow.com/questions/121162/what-does -The-явно-ключевое слово-в-с-средних – Gasim

ответ

1

Я получил ошибку en на a1.get() = 7; который говорит, что ни один оператор «=» не соответствует этим операндам

Там нет никакого способа, чтобы преобразовать 7 в A_Impl для operator=, так как конструктор A_Impl(T), который в этом случае расширяется до A_Impl(int), объявляются explicit.

Вы можете либо удалить explicit ключевое слово, или явно создать A_Impl с:

a1.get() = A_Impl(7); 

В качестве альтернативы вы можете также объявить конкретный operator=:

const A_Impl& operator=(const T&) 

для A_Impl класса.


Кроме того, если я беру явное слово будет компилировать, но я не понимаю разницу между функцией a1.get() и a1 = 13; который отлично работает даже с явным.

a1 = 13 прекрасно работает, потому что класс шаблона A имеет конструктор без явного к T (в частности A(T var)), который, в данном случае совпадают идеально подходит для T = int.


заметить также, что main всегда должен возвращать int, не void.

0

Вы только объявили оператор присваивания копии: const A_Impl& operator=(const A_Impl& a), но не оператор присваивания для T типов: const A_Impl& operator=(const T& a).

Если у вас нет конструктора explicit, ваш int (7) будет полностью преобразован в объект A_Impl, который затем будет присвоен вашей возвращенной ссылке.

Если конструктор explicit это implecit преобразование невозможно больше (тот, что на самом деле делает explicit), и, таким образом, нет никакой возможности назначить int к A_Impl. Что, однако будет работать, если ваш A_Impl класс является открытым, это (то же самое, что происходит под капотом, если вы не пишите explicit):

a1.get() = A_Impl(7);