DO>Компиляция проходит без ошибок и предупреждений. Справедлив ли такой код, и если да, то как правильно инстанцировать такой шаблон?
Хехе. Он справедлив, но вполне может быть не тем, что ты от него ожидаешь
Инстанцировать так:
template <class ret_t (*) (class args_t)>
class test
{
};
class ret_t{};
class args_t{};
ret_t fun(args_t);
int main()
{
test<fun> a;
}
Of course, the code must be complete enough to compile and link.
DO>Компиляция проходит без ошибок и предупреждений. Справедлив ли такой код, и если да, то как правильно инстанцировать такой шаблон?
Нет, не справедлив.
Справедливо либо это:
class ret_t{};
class args_t{};
template <ret_t (*) (args_t)>
class test
{
};
ret_t f1(args_t) { return ret_t(); }
ret_t f2(args_t) { return ret_t(); }
test<f1> t1;
test<f2> t2;
Либо вот это:
template <class ret_t2, class args_t2, ret_t2 (*fn) (args_t2)>
class test2
{
};
int f3 (double) { return 0; }
test2<ret_t, args_t, f1> t21;
test2<int, double, f3> t22;
Лучше расскажи, для чего все это, и что ты хочешь получить в конечном итоге.
Здравствуйте, Lorenzo_LAMAS, Вы писали:
L_L>Кстати, чтобы мой пример скомпилился, для mingw придется объявления классов перед шаблоном поместить L_L>А вижуалу и это не помогает.
Так, компилируется:
class ret_t;
class args_t;
template <ret_t (*) (args_t)>
class test
{
};
// class ret_t{};
// class args_t{};
ret_t fun(args_t);
test<&fun> a;
Если раскомментировать определения ret_t и args_t, вылазит ошибка:
.\main.cpp(26) : error C2440: 'specialization' : cannot convert from 'ret_t (__cdecl *)(args_t)' to 'ret_t (__cdecl *)(args_t)'
Incompatible calling conventions for UDT return value
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, Lorenzo_LAMAS, Вы писали:
L_L>Кстати, чтобы мой пример скомпилился, для mingw придется объявления классов перед шаблоном поместить L_L>А вижуалу и это не помогает.
Спасибо =) Я от этого пока ничего не ожидаю. Просто хотелось разобраться. Кстати, подобный пример, но с использованием typename уже не компилируется.
template <typename ret_t (*) (typename args_t)>
class test
{
};
Здравствуйте, Lorenzo_LAMAS, Вы писали:
DO>>Компиляция проходит без ошибок и предупреждений. Справедлив ли такой код, и если да, то как правильно инстанцировать такой шаблон? L_L>Хехе. Он справедлив, но вполне может быть не тем, что ты от него ожидаешь
Я правильно понял, что там идут просто "встроенные" форвард определения, как в friend class Х?
Правда она позволяет не делать это определение статической переменной даже если берётся её адрес. Как она умудряется? Непонятно...
Ну это я так отвлёкся немного...
Здравствуйте, Dr.Offset, Вы писали:
DO>Здравствуйте, Lorenzo_LAMAS, Вы писали:
L_L>>Кстати, чтобы мой пример скомпилился, для mingw придется объявления классов перед шаблоном поместить L_L>>А вижуалу и это не помогает.
DO>Спасибо =) Я от этого пока ничего не ожидаю. Просто хотелось разобраться. Кстати, подобный пример, но с использованием typename уже не компилируется.
Да, потому, что он уже неверный. А по твоей проблеме — как мне кажется, ответ Pretender в другом топике должен подойти.
Of course, the code must be complete enough to compile and link.
Здравствуйте, Lorenzo_LAMAS, Вы писали:
L_L>Видимо, встретив ключевое слово class, как в исходном примере, парсер вижуала уже не способен думать ни о чем другом, кроме как о параметре — типе.
И это, ИМХО, хорошо...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Lorenzo_LAMAS, Вы писали:
L_L>>Видимо, встретив ключевое слово class, как в исходном примере, парсер вижуала уже не способен думать ни о чем другом, кроме как о параметре — типе.
E>И это, ИМХО, хорошо...
Потому, что неправильно?
Of course, the code must be complete enough to compile and link.
Здравствуйте, Bell, Вы писали:
B>Лучше расскажи, для чего все это, и что ты хочешь получить в конечном итоге.
Да это так, исследование языка, так сказать... Конкретной задачи за этим не стоит.
Мне просто стразу показалось странным, что синонимичные понятия при определнии шаблона class и typename, оказывается даже в этом случае могут иметь разную семантику.
В этом примере class явно означает нечто иное, чем обозначение типа принимаемого шаблоном
template <class ret_t (*) (class args_t)>
class test
{
};
Тогда как в этом примере, все происходит как надо.
template <typename ret_t (*) (typename args_t)>
class test
{
};
Здравствуйте, Dr.Offset, Вы писали:
DO>Здравствуйте, Bell, Вы писали:
B>>Лучше расскажи, для чего все это, и что ты хочешь получить в конечном итоге.
DO>Да это так, исследование языка, так сказать... Конкретной задачи за этим не стоит. DO>Мне просто стразу показалось странным, что синонимичные понятия при определнии шаблона class и typename, оказывается даже в этом случае могут иметь разную семантику.
Это можно продемонстрировать проще:
template<class T*> class test{};
и
template<typename T*> class test{};
Вот поэтому, во избежание недоразумений, для обозначения типов, как параметров шаблона, лучше использовать ключевое слово typename вместо class.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, Lorenzo_LAMAS, Вы писали:
L_L>Потому, что неправильно?
А разве в аргументах шаблона можно объявлять новые типы? Вот так, например:
template<typename TRes, struct MyStruct{ TRes Res; } (*TFunc)(void)> class myClass;
Казалось бы, если так нельзя, то и предварительно не должно быть "льзя"...
А главное, зачем бы это надо?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Наверное, только ждать, пока разработчики пофиксят парсеры Я так понимаю, что даже комо начинает накрывать, когда он видит typename перед C<T>::MyT. Твой пример можно (для комо) так поправить, наверное: не использовать в определении вложенный тайпдеф, а использовать непосредственно C_Traits.
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Lorenzo_LAMAS, Вы писали:
L_L>>Потому, что неправильно? E>А разве в аргументах шаблона можно объявлять новые типы?
В параметрах. И потом, это не совсем объявление нового типа. Например, в параметрах функции нельзя объявлять новый тип (в С++ нельзя, в С- можно, хоть и бесполезно), но можно же писать такое:
void fun(struct A * p);
Но можно и поменять пример, написав:
class A{};
class B{};
template<class A (*)(class B)>
class test
{
};
Здесь то я, вроде, не объявляю новых типов?
E>А главное, зачем бы это надо?
Многие вопросы по С++ это не из разряда "я хочу писать такое уродство, а оно не компилится", а скорее
"чисто теоретически интересно, чего такое вот не компилится".
Of course, the code must be complete enough to compile and link.