2012-04-02 3 views
1

У меня есть класс с конструктором шаблона, и код на самом деле вызывает конструктор , после конструктора по умолчанию, который для меня не имеет смысла, поскольку тип неверен.Конструктор шаблонов C++, почему вы вызываете экземпляр-конструктор?

Например:

class A 
{ 
    public: 
    A(void); // default constructor 
    A(const A& other); // copy constructor 
    template<class TYPE> 
    A(const TYPE& object_to_ref); // template constructor 
}; 

Этот шаблон конструктор работы (правильно называется в других случаях), но не распознан как «правильный» конструктор из другой функции шаблона:

template<class TYPE> 
A& CreateA(const TYPE& object_to_ref) 
{ 
    // THIS FUNCTION IS NEVER SPECIALIZED WITH "A", ONLY WITH "B" !! 
    return *new A(object_to_ref); // CALLS "A::A(const A&)" !!?? 
} 

Пример неудачу:

B my_b; 
A& my_a = CreateA(my_b); // "A::A(const A&)" called, not "A::A(const B&)"! 

Это не имеет смысла для меня. Типы неправильны, чтобы соответствовать конструктору копирования. Что случилось? (MSVC2008)

Моя работа вокруг, чтобы не использовать конструктор шаблона в этом случае:

template<class TYPE> 
A& CreateA(const TYPE& object_to_ref) 
{ 
    A* new_a = new A(); //DEFAULT CONSTRUCTOR 
    new_a->setObjectToRef(object_to_ref); //OTHER TEMPLATE MEMBER FUNCTION 
    return *new_a; 
} 

ВОПРОС: Почему конструктор шаблона не вызывается в этом случае?

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

EDIT:B не имеет никакого отношения, без преобразования не указано между B и/или A:

class B 
{ 
}; 
+11

Тангенциальное примечание: код, который делает 'return * new', почти всегда плохая идея ... –

+3

Для значений почти абсурдно близко к 100%. –

+0

Если 'B' неявно конвертируется в' A', это происходит потому, что компилятор находит соответствующий конструктор, не требуя когда-либо генерировать код шаблона. – Chad

ответ

1

Вы не указали определение B, поэтому я собираюсь предположить, что A является предком B и B может быть неявным образом отбрасываться до A. В этом случае ваш шаблон для B не создается, потому что уже есть подходящий звонок.

+0

Извините, обновил вопрос, нет, 'B' не имеет отношения. Weird. – charley

+1

Это не имеет смысла. Вероятно, вы упростили свой пример. Есть ли другой неявный метод преобразования B в A? Как 'operator A()'? – cababunga

+0

Вы были правы: не имело смысла, я упростил. Было больше шаблонов <> ==> traits ==> template <> ', и один из них был неожиданным, но законным, в конечном итоге вызывающим в этом случае вызовом copy-constructor. Моя вина! (ХОРОШО! ЭТО БЫЛО ДВИЖЕНИЕ МЕНЯ КРАЗИ.) – charley

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