Аргументы шаблона
От: Dr.Offset  
Дата: 31.10.07 09:32
Оценка:
Компилирую этот код в mingw 3.4.5:

template <class ret_t (*) (class args_t)>
class test
{
};

Компиляция проходит без ошибок и предупреждений. Справедлив ли такой код, и если да, то как правильно инстанцировать такой шаблон?
Re: Аргументы шаблона
От: Lorenzo_LAMAS  
Дата: 31.10.07 09:44
Оценка: 12 (1) +1
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.
Re[2]: Аргументы шаблона
От: Lorenzo_LAMAS  
Дата: 31.10.07 09:52
Оценка:
Кстати, чтобы мой пример скомпилился, для mingw придется объявления классов перед шаблоном поместить
А вижуалу и это не помогает.
Of course, the code must be complete enough to compile and link.
Re: Аргументы шаблона
От: Bell Россия  
Дата: 31.10.07 10:14
Оценка: 1 (1) +1
Здравствуйте, Dr.Offset, Вы писали:

DO>Компилирую этот код в mingw 3.4.5:


DO>
DO>template <class ret_t (*) (class args_t)>
DO>class test
DO>{
DO>};
DO>

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;


Лучше расскажи, для чего все это, и что ты хочешь получить в конечном итоге.
Любите книгу — источник знаний (с) М.Горький
Re[3]: Глюк MVC 8.0
От: rg45 СССР  
Дата: 31.10.07 10:17
Оценка:
Здравствуйте, 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>>
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[4]: Глюк MVC 8.0
От: Lorenzo_LAMAS  
Дата: 31.10.07 10:22
Оценка:
оно при желании всяко компилируется, например так

struct ret_t{};
struct args_t{};

template <struct ret_t (*) (struct args_t)>
class test
{
};


ret_t fun(args_t);

int main()
{
   test<fun> a;
}


А вот если переставить определения структур — не хочет.

Видимо, встретив ключевое слово class, как в исходном примере, парсер вижуала уже не способен думать ни о чем другом, кроме как о параметре — типе.
Of course, the code must be complete enough to compile and link.
Re[3]: Аргументы шаблона
От: Dr.Offset  
Дата: 31.10.07 10:28
Оценка: :)
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>Кстати, чтобы мой пример скомпилился, для mingw придется объявления классов перед шаблоном поместить

L_L>А вижуалу и это не помогает.

Спасибо =) Я от этого пока ничего не ожидаю. Просто хотелось разобраться. Кстати, подобный пример, но с использованием typename уже не компилируется.

template <typename ret_t (*) (typename args_t)>
class test
{
};
Re[2]: Аргументы шаблона
От: remark Россия http://www.1024cores.net/
Дата: 31.10.07 10:29
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

DO>>Компиляция проходит без ошибок и предупреждений. Справедлив ли такой код, и если да, то как правильно инстанцировать такой шаблон?

L_L>Хехе. Он справедлив, но вполне может быть не тем, что ты от него ожидаешь


Я правильно понял, что там идут просто "встроенные" форвард определения, как в friend class Х?


У 2005 студии правда тут сносит крышу:

error C2917: 'ret_t (__cdecl *)(args_t)' : invalid template-parameter

Видимо от того, что она видит "template <class" и сразу заключает, что параметр-тип, и дальше не разбирается.

Хотя нет, тут не срывает:
template <typename type, typename type::inner_t value>
class test
{
};



А тут уже опять срывает:
template<typename T>
struct C
{
    typedef T MyT;
    
    template <MyT mv>
    struct CI
    {
     static MyT const myvalue = mv;
    };
};

template <typename T>
template <typename C<T>::MyT mv>
typename C<T>::MyT const
C<T>::CI<mv>::myvalue;


Правда она позволяет не делать это определение статической переменной даже если берётся её адрес. Как она умудряется? Непонятно...
Ну это я так отвлёкся немного...


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[4]: Аргументы шаблона
От: Lorenzo_LAMAS  
Дата: 31.10.07 10:38
Оценка:
Здравствуйте, 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.
Re[3]: Аргументы шаблона
От: Lorenzo_LAMAS  
Дата: 31.10.07 10:49
Оценка:
R>У 2005 студии правда тут сносит крышу:
R>

R>error C2917: 'ret_t (__cdecl *)(args_t)' : invalid template-parameter

R>Видимо от того, что она видит "template <class" и сразу заключает, что параметр-тип, и дальше не разбирается.

Я тоже это так понимаю. Причем сообщение

'specialization' : cannot convert from 'ret_t (__cdecl *)(args_t)' to 'ret_t (__cdecl *)(args_t)

вызывает подозрение, что все же как-то чего-то оно там все же разбирается
Of course, the code must be complete enough to compile and link.
Re[5]: И это, ИМХО, хорошо... :) (-)
От: Erop Россия  
Дата: 31.10.07 11:12
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>Видимо, встретив ключевое слово class, как в исходном примере, парсер вижуала уже не способен думать ни о чем другом, кроме как о параметре — типе.


И это, ИМХО, хорошо...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: И это, ИМХО, хорошо... :) (-)
От: Lorenzo_LAMAS  
Дата: 31.10.07 11:14
Оценка:
Здравствуйте, Erop, Вы писали:

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


L_L>>Видимо, встретив ключевое слово class, как в исходном примере, парсер вижуала уже не способен думать ни о чем другом, кроме как о параметре — типе.


E>И это, ИМХО, хорошо...

Потому, что неправильно?
Of course, the code must be complete enough to compile and link.
Re[2]: Аргументы шаблона
От: Dr.Offset  
Дата: 31.10.07 11:22
Оценка:
Здравствуйте, Bell, Вы писали:

B>Лучше расскажи, для чего все это, и что ты хочешь получить в конечном итоге.


Да это так, исследование языка, так сказать... Конкретной задачи за этим не стоит.
Мне просто стразу показалось странным, что синонимичные понятия при определнии шаблона class и typename, оказывается даже в этом случае могут иметь разную семантику.

В этом примере class явно означает нечто иное, чем обозначение типа принимаемого шаблоном
template <class ret_t (*) (class args_t)>
class test
{
};


Тогда как в этом примере, все происходит как надо.
template <typename ret_t (*) (typename args_t)>
class test
{
};
Re[3]: Аргументы шаблона
От: rg45 СССР  
Дата: 31.10.07 12:26
Оценка: +2
Здравствуйте, 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>>
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[3]: Аргументы шаблона
От: remark Россия http://www.1024cores.net/
Дата: 31.10.07 12:53
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

R>>А тут уже опять срывает:

R>>
R>>template<typename T>
R>>struct C
R>>{
R>>    typedef T MyT;
    
R>>    template <MyT mv>
R>>    struct CI
R>>    {
R>>     static MyT const myvalue = mv;
R>>    };
R>>};

R>>template <typename T>
R>>template <typename C<T>::MyT mv>
R>>typename C<T>::MyT const
R>>C<T>::CI<mv>::myvalue;
R>>


L_L>На этой крякозябре у кого хочешь ее сорвет. Например и у комо. Проще надо быть


L_L>
L_L>template<typename T>
L_L>struct C
L_L>{
L_L>    template <T mv>
L_L>    struct CI
L_L>    {
L_L>        static T const myvalue = mv;
L_L>    };
L_L>};

L_L>template <typename T>
L_L>template <T mv>
L_L>T const
L_L>C<T>::CI<mv>::myvalue;
L_L>



Это-то понятно. Это тоже первое, что я предложил (пример взят здесь
Автор: e-garin
Дата: 09.10.07
).
А что делать, если:

template<typename T>
struct C
{
    typedef typename C_Traits<T>::type MyT;
    
    template <MyT mv>
    struct CI
    {
     static MyT const myvalue = mv;
    };
};



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[7]: И это, ИМХО, хорошо... :) (-)
От: Erop Россия  
Дата: 31.10.07 13:03
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>Потому, что неправильно?

А разве в аргументах шаблона можно объявлять новые типы? Вот так, например:
template<typename TRes, struct MyStruct{ TRes Res; } (*TFunc)(void)> class myClass;

Казалось бы, если так нельзя, то и предварительно не должно быть "льзя"...

А главное, зачем бы это надо?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: Аргументы шаблона
От: Lorenzo_LAMAS  
Дата: 31.10.07 13:11
Оценка:
R>Это-то понятно. Это тоже первое, что я предложил

Я потому и удалил свой пост, что понял предназначение забойной крякозябристости

R>А что делать, если:


R>
R>template<typename T>
R>struct C
R>{
R>    typedef typename C_Traits<T>::type MyT;
    
R>    template <MyT mv>
R>    struct CI
R>    {
R>     static MyT const myvalue = mv;
R>    };
R>};
R>


Наверное, только ждать, пока разработчики пофиксят парсеры Я так понимаю, что даже комо начинает накрывать, когда он видит typename перед C<T>::MyT. Твой пример можно (для комо) так поправить, наверное: не использовать в определении вложенный тайпдеф, а использовать непосредственно C_Traits.
template<class T>
class C_Traits
{
public:
    typedef T type;
};

template<typename T>
struct C
{
    typedef typename C_Traits<T>::type MyT;
    
    template <MyT mv>
    struct CI
    {
        static MyT const myvalue = mv;
    };
};

template<class T>
template<typename C_Traits<T>::type mv>
typename C_Traits<T>::type const C<T>::CI<mv>::myvalue;
Of course, the code must be complete enough to compile and link.
Re[8]: И это, ИМХО, хорошо... :) (-)
От: Lorenzo_LAMAS  
Дата: 31.10.07 13:19
Оценка: :)
Здравствуйте, 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.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.