2011-12-26 2 views
6

Старый GCC 4.1.2 accepts, и новый GCC 4.5.1 accepts, следующая программа.Можно ли написать список параметров типа шаблона в объявлении конструктора?

Но действительно ли это правильно? Что говорит стандарт об объявлении конструктора с параметром шаблона типа?

(я нахожу интересным, что я не позволил do the same in the out-of-line definition.)

#include <iostream> 
template <typename T> 
struct Foo { 
    Foo<T>(); // <--- 
}; 

template <typename T> 
Foo<T>::Foo() { 
    std::cout << ":)"; 
} 

int main() { 
    Foo<int> f; 
} 

Я спрашиваю, что это было предложено в комментариях на this answer, что GCC может быть ошибочными здесь.

+0

FWIW, строит и работает на GCC 4.6.1 тоже. – Mat

+3

Предположительно из-за 12.1/1: «Синтаксис использует ... имя класса конструктора ...», этот вопрос равен «is» Foo 'имя класса?" –

+0

@SteveJessop: ... ", и если да, то почему это не принято в определении?" –

ответ

3

вложу почтовый копию возможного ДР недавно я послал на Рождество здесь

хорошо ли сформирован следующий код?

template<typename T> 
struct A { 
    A<T>(); 
}; 

Несколько компиляторы, которые я тестировал (лязг, г ++ и Комео conline) принять это. Действительно 12,1 не запрещает этого (A<T> этого имя этого класса и не имя ЬурейеГо), но 8.3p1 говорит

Безусловный-идентификатор происходящий в описателе-идентификаторе должен быть простым идентификатором, за исключением для объявления некоторых специальных функций (12.3, 12.4 , 13,5) ...

конструктор представляет собой специальную функцию член, но список перекрестных ссылок не включает в себя 12.1. Означает ли это, что приведенный выше код плохо сформирован? Или это случайное упущение?

Если вы сделаете то же самое в определении вне линии, вы попытаетесь передать аргументы шаблона конструктору. Это правильный код

struct A { 
    template<typename T> A(); 
}; 

template<> A::A<int>() { } 

Спецификация говорит, что, когда вводится имя класса используется в квалифицированном имени при поиске в области видимости класса (так же, как и в A::A), а затем, когда поиск имени принимает функции/имена конструктора , ссылка на введенное имя класса будет переведена для разрешения на конструктор (ы) этого класса (если контекст поиска имени принимает только типы, то имя останется именем введенного класса и будет обозначать тип класса). После A::A поиск по имени завершен и дает конструктор. Затем <int> может быть проанализирован только как список аргументов шаблона. Если среди ваших конструкторов нет шаблона, ваш код будет недействительным.

+0

Первый абзац означает, что данный код действителен. Но errr ... OP задал вопрос о регулярном конструкторе класса шаблона, а не о шаблоном конструкторе. ('A :: A()' i.s.o. 'A :: A ()'). – xtofl

+0

@xtofl Я думаю, вы неправильно поняли мой ответ. После копии моей почты я подробно остановился на вопросе OP («Мне интересно, что мне не разрешено делать то же самое в определении вне очереди»). Первый абзац (цитата, представляющая мою почту) подразумевает, что код принят GCC, clang и онлайн-компилятором goau. Это не означает, что код действителен. –

+0

Прошу прощения; Я умный парень, но можете ли вы обобщить это для меня? –

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