Шаблоны C : Byval / Reference, мешающие друг другу

#c #templates

#c #шаблоны

Вопрос:

Вот упрощенная версия моей проблемы. У меня есть класс свойств. В нем есть данные типа has_initalized и такие, которые я удалил для этого примера.

Когда я вызываю функцию, которая использует T, это нормально. Однако это не так, поэтому я решил написать его версию T amp;. Но это приводит к тому, что все функции, использующие обычный T, выдают ошибку компиляции. Почему T amp; вмешивается в это? Для этого примера, как мне заставить обе функции (Q и W) работать без изменения main ()?

 template <class T>
class Property {
    T v;
    Property(Propertyamp;p) { }
public:
    Property() {}
    T operator=(T src) { v = src; return v; }
    operator T() const { return v; }
    operator Tamp;() const{ return v; }
    T operator->() { return v; }
};

class A{};

void Q(A  s){}
void W(Aamp; s){}

int main(){
    Property<A> a;
    Q(a);
    W(a);
}
  

Комментарии:

1. Серьезно, я не могу понять вопрос и проблему.

2. @Nawaz: Попробуйте скомпилировать это

3. -1 за то, что сказал мне об этом Try compiling it . Почему я должен? Вы не можете сами сообщить нам об ошибке и проблеме?

4. В чем смысл этого кода? Зачем вам писать это с самого начала?

Ответ №1:

В правилах перегрузки C нет ничего, что позволяло бы компилятору выбирать между operatorT() и operatorTamp;() при вызове Q. Поэтому удаление

 operator T() const { return v; }
  

также устранит двусмысленность. Но тогда у вас возникнет проблема, потому что возврат неконстантной ссылки на элемент в функции const невозможен.

Ответ №2:

Для вашего Q вы можете использовать обе функции преобразования. Вы можете заставить компилятор предпочесть один другому, сделав один из них неконстантным.

 operator T() const { return v; }
operator Tamp;() { return v; }
  

Теперь для Q , operator Tamp; взято. Этот способ также исправит вызов W для получения неконстантной ссылки. Вы также можете возвращать постоянную ссылку из другого

 operator T constamp;() const { return v; }
operator Tamp;() { return v; }
  

Этот способ по-прежнему предпочтительнее использовать вторую функцию преобразования для Q , но если ваш объект a является const и вы инициализируете ссылку const, вам не всегда потребуется копировать v .