2010-11-09 4 views
0

Позвольте мне продемонстрировать на простом примере:копия определения конструктора/преобразования (Const/неконстантные)

class A 
{ 
public: 
    A() { cout << "A::A()" << endl; } 
    A(A const& a) : _a(a._a) { cout << "A::(A Copy Const)" << endl; } 
    A(A& a) : _a(a._a) { cout << "A::(A Copy)" << endl; } 

    template <typename _T1> 
    A(_T1& v1) : _a(v1) { cout << "A::(T conversion)" << endl; } 

    ~A() { cout << "A::~A()" << endl; } 

    void say() { cout << "A::say()" << endl; } 

private: 
    int _a; 
}; 

int main(int argc, char* argv[]) 
{ 
    A a1(A(argc)); // Line 1: ERM? 

    a1.say(); 

    return 0; 
} 

Пара вещей:

Есть ли вред при определении константный и неконстантная версия конструктора копирования? Причина я сделал это, что это, по-видимому помогает компилятор отличить от шаблонного конструктора, т.е.

A const a1(argc); 
A a2(a1); // <-- correctly call the const copy ctor 

A a3(argc); 
A a4(a3); // <-- correctly call the non-const copy ctor 

Есть ли лучший способ гарантировать, что в приведенном выше примере, конструктор копирования всегда вызывается через шаблонный конструктор ?

Во-вторых, с точки зрения чистого кодирования линия 1 выглядит нормально, предполагается создание временного A с argc, а затем запуск конструктора копирования, однако я получаю следующее исключение (gcc 4.4.4):

ошибка: запрос члена «сказать» в «a1», который является не-класса типа «A (A)»

Я считаю, что здесь происходит, что компилятор считает, что a1 является определение функции, это правильно? Если да, то каков правильный способ написать эту конкретную строку кода? Следующее выглядит как взлома!

A a1(true ? A(argc) : A()); 

p.s. Пожалуйста, проигнорируйте все стилистические фобары и почему именно я хочу это сделать ...! :)

ответ

2

Шаблонный конструктор никогда не является (формальным) экземпляром копии.

Вы правы, что объявление, которое может быть объявлением функции, рассматривается как объявление функции. Это называется «самым неприятным анализом» на C++. Одним из способов является использование дополнительных круглых скобок, таких как T v((U)).

Возможно, это добавит ключевое слово auto, но я не пробовал. Но так как auto получает новый смысл в C++ 0x, вероятно, неплохо привыкнуть к его использованию, даже если он работает для этой проблемы на C++ 98.

Cheers & hth.

+0

auto, похоже, не работает на C++ 98, но скобка сделала трюк! Спасибо. – Nim

Смежные вопросы