«Нет подходящей функции для ошибки вызова» с g ++ - PullRequest
0 голосов
/ 09 марта 2011

У меня есть класс A

template<typename T>
class A : public std::auto_ptr<T>
{
    typedef std::auto_ptr<T> Super;
public:
    A() : Super() { }
    A(T* t) : Super(t) { }
    A(A<T>& o) : Super(o) { }
    ...
};

и IConstEnumerator

template<typename T>
struct IConstEnumerator
{
    ...   
virtual IEnumerator<T>* GetEnumerator() = 0;
virtual IConstEnumerator<T>* GetEnumerator() const = 0;      
};

Когда я запускаю этот код

AP< IConstEnumerator<IPort> > pe = node.GetPorts().GetEnumerator(); ;

Я получаю ошибки из-за отсутствия правильного соответствияс компилятором g ++.

error: no matching function for call to ‘AIR::A<AIR::IConstEnumerator<AIR::IPort> >::AP(AIR::A<AIR::IConstEnumerator<AIR::IPort> >)’
note: candidates are: AIR::A<T>::A(AIR::A<T>&) [with T = AIR::IConstEnumerator<AIR::IPort>]
note:                 AIR::A<T>::A(T*) [with T = AIR::IConstEnumerator<AIR::IPort>]

Что не так с классом А?Он хорошо работает с MSVC.

EDIT

Использование конструктора копирования явно решает эту проблему.A< IConstEnumerator<IPort> > pe(node.GetPorts().GetEnumerator())

Ответы [ 4 ]

3 голосов
/ 09 марта 2011

Ваш A конструктор копирования получает аргумент по неконстантной ссылке:

A(A<T>& o) : Super(o) { }
      ^ not const

Ваш пример, вероятно, пытается скопировать временный объект, и неконстантная ссылка не может привязаться к временному объекту. Visual C ++ имеет злое расширение, которое позволяет этому работать; вы должны быть осторожны, чтобы не полагаться на это расширение, если хотите, чтобы ваш код был переносимым.

Если вы пытаетесь имитировать конструктор копирования auto_ptr, вам также необходимо реализовать что-то похожее на auto_ptr_ref, которое используется в качестве помощника, чтобы разрешить копирование временных auto_ptr s. Я описываю, как это достигается в принятом ответе на Как можно реализовать конструктор копирования std::auto_ptr?

Для чего это стоит, вывод из std::auto_ptr немного странный; по возможности используйте композицию вместо наследования (в std::auto_ptr не так уж много всего, что вы бы извлекли из нее пользу в любом случае).

2 голосов
/ 09 марта 2011

Без точного кода, который на самом деле вызывает ошибку, трудно точно знать, но я подозреваю, что из AIR::A<T>::A(AIR::A<T>&) происходит то, что вы пытаетесь передать временный (возможно неявный) объект в AIR::A<T>::A, и MSVC позволяет вы связываете временный параметр с неконстантным ссылочным параметром, в то время как g ++ вполне правильно запрещает это. Вы можете сделать параметр const?

0 голосов
/ 09 марта 2011

Похоже, компилятор говорит, что не может выбрать правильную функцию: конструктор A из указателя A<T>::A(T*) или конструктор копирования A<T>::A(A<T> &). Может быть, стоит изменить определение на explicit A(T* t) : Super(t) { }

0 голосов
/ 09 марта 2011

Я думаю, вам не хватает A(A<T> const & o).

VS (неверно) позволяет получить неконстантную ссылку на временный объект, g ++ ведет себя правильно

...