Рассмотрим этот код: компиляторы
template <int N>
struct X
{
friend void f(X *) {}
};
int main()
{
f((X<0> *)0); // Error?
}
, похоже, сильно не согласны. (MSVC08 / 10 говорит нет, GCC <4.5 говорит да, но 4.5 говорит нет, вс 5.1 говорит да, intel 11.1 тоже говорит да, но comeau говорит нет (оба EDG)).
Согласно «Шаблонам C ++ - Полное руководство»:
... предполагается, что вызов с поиском друзей в связанные классы на самом деле вызывает класс должен быть создан ... Хотя это было явно задумано теми, кто написал стандарт C ++, это не четко прописано в стандарте.
Я не смог найти соответствующий раздел в стандарте. Любая ссылка?
Рассмотрите этот вариант:
template <int N>
struct X
{
template <int M>
friend void f(X<M> *) {}
};
template <>
struct X<0>
{
};
int main()
{
X<1>();
f((X<0> *)0); // Error?
}
Ключевой вопрос здесь заключается в том, должна ли жизнеспособная функция, введенная X <1>
, быть видимой во время ADL для X <0>
? Они связаны? Все компиляторы, упомянутые выше, принимают этот код, кроме Comeau, который принимает его только в расслабленном режиме. Не уверен, что и стандарт говорит об этом.
Как вы к этому относитесь?