2013-11-24 4 views
5

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

Я пытаюсь получить класс из форсированного кортежа. Кортежи Boost предоставляют метод get() для доступа к отдельным полям. Интересно, что я не могу использовать метод из производного класса.

Следующий код показывает проблему:

#include <iostream> 
#include <boost/tuple/tuple.hpp> 
using namespace std; 

template<typename A> 
class Derived : public boost::tuple<A> 
{ 
public: 
    Derived() : boost::tuple<A>() {} 

    A& getVal0() 
    { 
     return get<0>(); 
     // does not compile: 
     //error: 'get' was not declared in this scope 

     return boost::tuple<A>::get<0>(); 
     // does not compile 
     //error: expected primary-expression before ')' token 

     return boost::tuples::get<0>(*this); 
     //works 
    } 
}; 

int main() { 
    Derived<int> a; 

    a.get<0>() = 5; 

    cout << a.get<0>() << endl; 
    cout << a.getVal0() << endl; 
    return 0; 
} 

Интересно, почему я могу получить доступ к методу get<0>() от основной функции

a.get<0>() = 5; 

но не внутри A& getVal0() метода:

error: 'get' was not declared in this scope 

Вторая обратная линия была моей попыткой sc ОПЕ вызов метода в базовом классе:

return boost::tuple<A>::get<0>(); 

И это порождает различные ошибки

error: expected primary-expression before ')' token 

Вызов внешней функции `подталкивания :: кортежи :: получить < 0> (* это) работает. И это обходное решение для меня в порядке. Но я все еще удивляюсь, почему я не могу использовать метод кортежа на этом этапе.

В документации повышающего это уведомление для Visual C++

Внимание! Функции-члены get не поддерживаются компилятором MS Visual C++. Кроме того, у компилятора есть проблемы с поиском функций, не входящих в члены, без явного определения пространства имен. Следовательно, все вызовы get должны быть квалифицированы как: tuples :: get (a_tuple) при написании кода, который должен компилироваться с MSVC++ 6.0.

Но я использую GCC 4.5.2 & 4.8.1

Заранее спасибо

+5

+1 Я должен сказать следующее: в этом случае вопрос должен быть приведен в качестве примера любому новому пользователю, который размещает на этом сайте. У вас есть * все * необходимое для хорошего вопроса, в том числе (1) проблема, которую вы считаете у вас, (2) образец кода, который показывает эту проблему, (3) попытки решить проблему; (4) каждый результат этих (5) используемые вами инструменты, включая информацию о версии, и (6) исследование того, что, по вашему мнению, может быть проблемой root. Для должности в целом это потрясающе; для * первой * почты это просто выдающийся и редко встречается с такой доставкой. – WhozCraig

+0

WhozCraig очень приятно, что вы можете дать новику так много хороших слов и положительных советов – 4pie0

+0

@ piotruś Не сложно, когда будет опубликован такой вопрос. Я очень серьезно отношусь к этому образцово. Я просто надеюсь, что OP знает, как отметить решение, потому что я уверен, что у него есть Dietmar. = P – WhozCraig

ответ

3

Предполагая, что есть шаблон функции а get<I>() элемент в базовом классе, вы, вероятно, хотите использовать

this->template get<0>() 

Часть this необходима, чтобы сделать ее зависимой от вас (вы можете также использовать надлежащую квалификацию класса, но это немного боль и ненужные sary, если вы не скрываете имя базового класса). Часть template необходима, чтобы сообщить компилятору, что зависимым именем (get) является шаблон.

Основная причина, почему this (или какой-либо другой квалификации) и template необходимы является составление модели две фазы для шаблонов:

  • Любое название, которое сразу не зависит от аргумента шаблона в той или иной форме является искал только во время фазы I, т. е. в контексте, где задан шаблон. Поскольку аргумент шаблона неизвестен и, таким образом, точное расположение базового класса неизвестно (оно может быть специализированным), любое имя в базовом классе игнорируется. Использование любой квалификации, заставляющей имя зависеть от аргумента шаблона, например., используя this->, перемещает поиск в фазу II, то есть при создании экземпляра шаблона.
  • После того, как имя зависит от ситуации, возникает двусмысленность, если выражение включает символ <, в то время как шаблон анализируется в фазе I, т. Е. Когда аргументы шаблона еще неизвестны: < может быть либо началом явный аргумент шаблона для вызова функции-члена или он может быть меньше, чем оператор. Поскольку явное упоминание аргументов шаблона редко (ну, по крайней мере, это было редко, когда эти правила были сделаны), по умолчанию он считается менее оператором. Чтобы указать, что имя на самом деле является шаблоном функции-члена с явно указанным аргументом шаблона, ему должно предшествовать ключевое слово template (очень похожее на типы, требующие typename).
+0

Большой вопрос, почему это происходит. Благодаря подсказке «this-> template» я нашел [link] (http://stackoverflow.com/questions/5533354/what-does-a-call-to-this-template-somename-do). $ C.13.6 в Stroustrups Язык программирования C++ объясняет эту проблему. Но я все еще не уверен, почему это необходимо в производном классе. –

+0

@EvilAzrael: Я добавил некоторое объяснение в ответ. –

+0

Спасибо за объяснение. :-) –

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