При попытке скомпилировать следующий код Visual Studio Express 2005 выдаёт ошибку компиляции "unable to match function definition to an existing declaration". При этом GCC и даже Borland C++5.5 компилируют его без каких-либо проблем. С чем может быть связана эта ошибка и можно ли считать её ошибкой компилятора? Является ли этот код допустимым по стандарту языка?
template <class F>
class Container
{
public:
class Iterator
{
friend class Container<F>;
Iterator(int (&values)[F::Count]);
int (&values_)[F::Count];
};
Iterator begin()
{
return Iterator(values_);
}
private:
int values_[F::Count];
};
template <class F>
Container<F>::Iterator::Iterator(int (&values)[F::Count]) : values_(values)
{}
class SomeF
{
public:
static const int Count = 10;
};
int main(int argc, char *argv[])
{
Container<SomeF> container;
}
Привет. Стандарт не читал, не знаю. Но возможно чем-нибудь помогу.
Например, вот этот код скомпилируется думаю везде, хотя не знаю почему студия не компилит твой код(
она почему то считает что тип параметра который указан в объявлении не соответствует типу параметра, который используется в определении ) :
template <typename F>
class Container
{
public:
class Iterator
{
typedef int (&MasInt) [F::Count];
friend class Container<F>;
Iterator(MasInt);
MasInt values_;
};
Iterator begin()
{
return Iterator(values_);
}
private:
int values_[F::Count];
};
template <typename F>
Container<F>::Iterator::Iterator(MasInt values) : values_(values)
{
}
class SomeF
{
public:
static const int Count = 10;
};
Здравствуйте, LightGreen, Вы писали:
LG>При попытке скомпилировать следующий код Visual Studio Express 2005 выдаёт ошибку компиляции "unable to match function definition to an existing declaration". При этом GCC и даже Borland C++5.5 компилируют его без каких-либо проблем. С чем может быть связана эта ошибка и можно ли считать её ошибкой компилятора? Является ли этот код допустимым по стандарту языка? LG>[snipped]
Неужели так трудно хоть чуть-чуть минимизировать пример? Проблема ведь воспроизводится гораздо меньшим количеством строк:
template <typename T>
struct A
{
void foo(int (&values)[T::Count]);
};
template <typename T>
void A<T>::foo(int (&values)[T::Count]) //error C2244: 'A<T>::foo' : unable to match function definition to an existing declaration
{
}
Не берусь судить, насколько такое поведение соответствует (или наоборот, не соответствует) стандарту, но о причине ошибки догадаться не трудно: у компилятора в первой фазе просто нет информации о том, что T::Count имеет целочисленный тип, соответственно, он не может прийти к выводу о том, что декларатор int (&values)[T::Count] обозначает ссылку на массив. Если немного ему помочь, все приходит в порядок:
Здравствуйте, rg45, Вы писали:
R>Неужели так трудно хоть чуть-чуть минимизировать пример? Проблема ведь воспроизводится гораздо меньшим количеством строк:
Чуть-чуть уже минимизировано — убрано 95% кода. Вы убрали ещё несколько процентов, честь Вам и хвала.
R>Не берусь судить, насколько такое поведение соответствует (или наоборот, не соответствует) стандарту, но о причине ошибки догадаться не трудно: у компилятора в первой фазе просто нет информации о том, что T::Count имеет целочисленный тип, соответственно, он не может прийти к выводу о том, что декларатор int (&values)[T::Count] обозначает ссылку на массив. Если немного ему помочь, все приходит в порядок:
Спасибо за объяснение! Но почему тогда другие компиляторы, тот же GCC или древний Borland, спокойно этот код компилируют? У них в первой фазе есть вся информация??
Здравствуйте, LightGreen, Вы писали:
LG>Спасибо за объяснение! Но почему тогда другие компиляторы, тот же GCC или древний Borland, спокойно этот код компилируют? У них в первой фазе есть вся информация??
Сходу не берусь объяснить, тут нужно время, чтоб внимательно посмотреть стандарт. Может, кто-то из знатоков объяснит.
--
Справедливость выше закона. А человечность выше справедливости.
R>Не берусь судить, насколько такое поведение соответствует (или наоборот, не соответствует) стандарту, но о причине ошибки догадаться не трудно: у компилятора в первой фазе просто нет информации о том, что T::Count имеет целочисленный тип, соответственно, он не может прийти к выводу о том, что декларатор int (&values)[T::Count] обозначает ссылку на массив. Если немного ему помочь, все приходит в порядок: R>
R>>Не берусь судить, насколько такое поведение соответствует (или наоборот, не соответствует) стандарту, но о причине ошибки догадаться не трудно: у компилятора в первой фазе просто нет информации о том, что T::Count имеет целочисленный тип, соответственно, он не может прийти к выводу о том, что декларатор int (&values)[T::Count] обозначает ссылку на массив. Если немного ему помочь, все приходит в порядок: R>>[...]
PS>если бы так было, то не компилировался бы следущий код
PS>template <typename T> PS>struct A PS>{ PS> void foo(int (&values)[T::Count]) PS> { PS> } PS>};
Я думаю, что это таки ошибка компилятора, которая проявляется при определенных условиях.
--
Справедливость выше закона. А человечность выше справедливости.