Шаблонная функция член класса
От: _NN_ www.nemerleweb.com
Дата: 20.08.15 19:22
Оценка:
В общем так.
Код без шаблона не собирается потому как не корректный:

struct AA
{
    using X = void();

    X x;
};
//AA::X AA::x{}; // Так нельзя

void AA::x() { } // Нет проблем


С шаблонами выходит всё веселее:
struct A
{
    template<class T>
    using X = void();
    
    template<class T>
    X<T> x;
};
template<class T>
A::X<T> A::x{};

Компилируется в GCC и VC
Clang:
error: out-of-line declaration of a member must be a definition [-Wout-of-line-declaration]
!!error: illegal initializer (only variables can be initialized)


Хочу заметить, что VC позволяет писать без ';' в конце т.е. A::X<T> A::x{};

А далее разные компиляторы дают разный результат.
void TestA()
{
    A a;
    a.x<int>();
}


VC: Всё собирается и работает.
GCC: undefined reference to `void A::x<int>()'

Как обычно вопрос кто здесь прав ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Шаблонная функция член класса
От: yatagarasu Беларусь  
Дата: 20.08.15 20:35
Оценка: +1
Здравствуйте, _NN_, Вы писали:


_NN> using X = void();

_NN>AA::X AA::x{};

Объясните что тут вообще происходит?
Re: Шаблонная функция член класса
От: dead0k  
Дата: 21.08.15 07:08
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Как обычно вопрос кто здесь прав ?

Шланг, ессно. VC не может быть прав по определению, следовательно и gcc тоже на кривую дорожку вылез.
</s>
Re[2]: Шаблонная функция член класса
От: dead0k  
Дата: 21.08.15 07:13
Оценка:
Здравствуйте, yatagarasu, Вы писали:

Y>Здравствуйте, _NN_, Вы писали:



_NN>> using X = void();

_NN>>AA::X AA::x{};

Y>Объясните что тут вообще происходит?

— либо определение метода AA::x, возвращающего указатель на функцию void() — но в AA нет такого метода, так-что
— инициализация члена AA:x, являющегося указателем на функцию void() (но список инициализации пуст, потому шланг и ругается)
Re[3]: Шаблонная функция член класса
От: _NN_ www.nemerleweb.com
Дата: 21.08.15 10:27
Оценка:
_NN>>> using X = void();
_NN>>>AA::X AA::x{};

Y>>Объясните что тут вообще происходит?

D>- либо определение метода AA::x, возвращающего указатель на функцию void() — но в AA нет такого метода, так-что
D>- инициализация члена AA:x, являющегося указателем на функцию void() (но список инициализации пуст, потому шланг и ругается)
Почему это указатель на функцию ?
X = void() .
X x = void x();

struct A { using X = void(); X x; }
void A::x() {}

Тут нет никакого указателя.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: Шаблонная функция член класса
От: dead0k  
Дата: 21.08.15 11:38
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>>>> using X = void();

_NN>Тут нет никакого указателя.
А, ну да, тогда наврал. Мне почему-то всегда казалось что разницы между функцией и указателем на функцию в объявлениях нет.
Отредактировано 21.08.2015 11:40 dead0k . Предыдущая версия .
Re: Шаблонная функция член класса
От: wander  
Дата: 04.09.15 20:07
Оценка:
Здравствуйте, _NN_, Вы писали:
_NN>С шаблонами выходит всё веселее:
_NN>
_NN>struct A
_NN>{
_NN>    template<class T>
_NN>    using X = void();
    
_NN>    template<class T>
_NN>    X<T> x;
_NN>};
_NN>template<class T>
_NN>A::X<T> A::x{};
_NN>

_NN>Компилируется в GCC и VC
_NN>Clang:
error: out-of-line declaration of a member must be a definition [-Wout-of-line-declaration]
_NN>!!error: illegal initializer (only variables can be initialized)
_NN>


_NN>Как обычно вопрос кто здесь прав ?


В стандарты не лазил, но исходя из здравого смысла, конструкция
_NN>template<class T>
_NN>A::X<T> A::x{};

— это ведь не определение метода.
Определение метода было бы вот:
template <typename T>
typename return_type<A::X<T>>::type A::x(){ }

  "Развернуть"
template <typename fT>
struct return_type;

template <typename R, typename ...Args>
struct return_type<R(Args...)>
{
    using type = R;
};

struct A
{
    template <class T>
    using X = void();    
    
    template <class T>
    X<T> x;
};

template <typename T>
typename return_type<A::X<T>>::type A::x(){ }

Так что мне кажется однозначно прав clang. Не смотря на то, что в VS мой последний код не компилируется
Re[2]: Шаблонная функция член класса
От: _NN_ www.nemerleweb.com
Дата: 05.09.15 07:16
Оценка:
Здравствуйте, wander, Вы писали:

W>Так что мне кажется однозначно прав clang. Не смотря на то, что в VS мой последний код не компилируется


GCC тоже не осилил.
Я не уверен насколько это корректный код.
Надо в clang проверить
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: Шаблонная функция член класса
От: wander  
Дата: 05.09.15 16:48
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>GCC тоже не осилил.

_NN>Я не уверен насколько это корректный код.
_NN>Надо в clang проверить

Как это на осилил!!?
А вот (4.9.2): http://rextester.com/KBRX55288
И clang (3.6.0): http://rextester.com/UPSUE84191

Так что может он и некорректный, но по крайней мере коррелирует со здравым смыслом.

PS. вывод cl.exe: http://rextester.com/IKW31533
Отредактировано 05.09.2015 16:56 wander . Предыдущая версия . Еще …
Отредактировано 05.09.2015 16:49 wander (он -> но) . Предыдущая версия .
Re[4]: Шаблонная функция член класса
От: _NN_ www.nemerleweb.com
Дата: 05.09.15 17:12
Оценка:
Здравствуйте, wander, Вы писали:

W>Как это на осилил!!?

Я тестировал на ideone.com: https://ideone.com/i3JFpY

Спасибо за еще один ресурс онлайн компилятора.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[5]: Шаблонная функция член класса
От: wander  
Дата: 05.09.15 19:59
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Здравствуйте, wander, Вы писали:


W>>Как это на осилил!!?

_NN>Я тестировал на ideone.com: https://ideone.com/i3JFpY

Посмотрел на его ошибки:

prog.cpp:25:32: error: 'type' in 'struct return_type<A::X<T> >' does not name a type
typename return_type<A::X<T>>::type A::x()
^
prog.cpp:25:37: error: prototype for 'int A::x()' does not match any in class 'A'
typename return_type<A::X<T>>::type A::x()
^
prog.cpp:21:10: error: candidate is: template<class T> void A::x()
X<T> x;

Что-то у меня большое подозрение, что он лажает.
A::X<T> — это void(), void() — это тип функции. Шаблон return_type выделяет тип void из типа void().
А тут, он получается не смог это сделать. Хотя, если посмотреть какой тип имеет X<T>, то явно показывает, что void(). Непонятно!

_NN>Спасибо за еще один ресурс онлайн компилятора.



UPD:
Починил пример, через указатель на функцию:
https://ideone.com/UUKe0L
Отредактировано 05.09.2015 20:13 wander . Предыдущая версия . Еще …
Отредактировано 05.09.2015 20:13 wander . Предыдущая версия .
Re[6]: Шаблонная функция член класса
От: _NN_ www.nemerleweb.com
Дата: 06.09.15 13:13
Оценка: +1
Здравствуйте, wander, Вы писали:

В общем ждём починки.
http://rsdn.nemerleweb.com
http://nemerleweb.com
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.