LINUX.ORG.RU

Локальный класс-Ошибка моя или gcc


0

0

Почему вот такой код срабатывает

class SequenceFunctor: public unary_function<const Dna&,void>
{
public:
SequenceFunctor(int length_sequence=3):m_length_seq(length_sequence)
{};

void operator()(const Dna&d)
{
...
}
protected:
int m_length_seq;
};
void SequenceAnalise::analise(const Population&p)
{

SequenceFunctor csf;
SequenceFunctor result=for_each(p.begin(),p.end(),csf);
}



А такой нет

void SequenceAnalise::analise(const Population&p)
{
class SequenceFunctor: public unary_function<const Dna&,void>
{
public:
SequenceFunctor(int length_sequence=3):m_length_seq(length_sequence)
{};

void operator()(const Dna&d)
{
...
}
protected:
int m_length_seq;
};


SequenceFunctor csf;
SequenceFunctor result=for_each(p.begin(),p.end(),csf);
}

компилятор: gcc (GCC) 4.1.2 (Ubuntu 4.1.2-0ubuntu4)


Ответ на: комментарий от dilmah

Сорри!! :) Забыл
sequence_analise.cpp: In member function ‘void SequenceAnalise::analise(const Population&)’:sequence_analise.cpp:35: error: no matching function for call to ‘for_each(__gnu_cxx::__normal_iterator<const Dna*, std::vector<Dna, std::allocator<Dna> > >, __gnu_cxx::__normal_iterator<const Dna*, std::vector<Dna, std::allocator<Dna> > >, SequenceAnalise::analise(const Population&)::CalcSequenceFunctor&)’
sequence_analise.cpp:35: warning: unused variable ‘result’
make: *** [sequence_analise.o] Error 1
make: *** Waiting for unfinished jobs....

lsv
() автор топика
Ответ на: комментарий от lsv

Это не баг, это фича!

Поясню на более простом примере.

$cat foo.cc

#include <vector>
#include <algorithm>

int f(const int y = 0)
{
struct S
{
int x;
void operator()(const int a)
{
x += a;
}
};
std::vector<int> v(2);
v[0] = 1;
v[1] = 2;
S o;
S n = std::for_each(v.begin(), v.end(), o);
int r = y + n.x;
return r;
}

int main(int argc, char** argv)
{
int t = f();
return t;
}

foo.cc: In function ‘int f(int)’:
foo.cc:18: error: no matching function for call to ‘for_each(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, f(int)::S&)’

Область видимости класса S, объявленного внутри функции f, (и всех его
членов, методов, конструкторов и деструкторов) -- это функция f. Кстати,
имя этого типа -- f(int)::S. Создать объект этого типа, вызвать его метод,
etc. можно только внутри тела функции f. Потому (шаблонная) функция
std::for_each не может вызвать ни метод f(int)::S::operator(const int),
ни (копирующий) конструктор f(int)::S(const f(int)::S&). Шаблон не
инстанцируется, и g++ често на это жалуется.

Dselect ★★★
()
Ответ на: комментарий от max_posedon

> у вас ошибка не в этом файле,

Как раз таки в этом (см. пример, который я привел).

> научитесь читать и постить *весь* вывод

Хотя автор вопроса -- тот еще партизан, но прежде чем отвечать, надо
думать, хотя бы чуток.

Dselect ★★★
()
Ответ на: Это не баг, это фича! от Dselect

> Область видимости класса S, объявленного внутри функции f, (и всех его членов, методов, конструкторов и деструкторов) -- это функция f. Кстати, имя этого типа -- f(int)::S. Создать объект этого типа, вызвать его метод, etc. можно только внутри тела функции f. Потому (шаблонная) функция std::for_each не может вызвать ни метод f(int)::S::operator(const int), ни (копирующий) конструктор f(int)::S(const f(int)::S&). Шаблон не инстанцируется, и g++ често на это жалуется.

По моему не совсем так. Область видимости не при чем. Дело вот в этой фразе: "Member functions of a local class (class.local) have no linkage."

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1353.html

dilmah ★★★★★
()
Ответ на: комментарий от dilmah

> По моему не совсем так. Область видимости не при чем. Дело вот
> в этой фразе: "Member functions of a local class (class.local)
> have no linkage."

Не понимаю. До linkage дело еще не дошло (и вряд ли возникли бы
какие-то проблемы -- компилятор встроил бы все вызовы). IMHO, дело
именно в том, что шаблон невозможно инстанцировать, потому как объявление
(локального) класса недоступно (и не может быть доступным). Т.е., если
бы шаблон for_each можно было объявить/определить внутри той же функции
(по стандарту, AFAIK, нельзя), код бы работал.

Dselect ★★★
()
Ответ на: комментарий от Dselect

> Не понимаю. До linkage дело еще не дошло (и вряд ли возникли бы какие-то проблемы -- компилятор встроил бы все вызовы).

ну вот смотри. Область видимости это scope. Вот определение что означает linkage:

When a name has external linkage, the entity it denotes can be referred to by names from scopes of other translation units or from other scopes of the same translation unit.

When a name has internal linkage, the entity it denotes can be referred to by names from other scopes in the same translation unit. When a name has no linkage, the entity it denotes cannot be referred to by names from other scopes.

То есть если у имени есть linkage то оно может быть использовано вне своей области видимости. Если бы у членов сабжевого класса был linkage, for_each нормально сработал бы. В данном случае no linkage -- значит оно не может быть использовано вне своей области видимости.

dilmah ★★★★★
()
Ответ на: комментарий от dilmah

> Если бы у членов сабжевого класса был linkage, for_each нормально сработал бы.
> В данном случае no linkage -- значит оно не может быть использовано вне
> своей области видимости.

Понял. Спасибо за объяснение.

Dselect ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.