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: Аргументы шаблона
От: 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]: Аргументы шаблона
От: 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]: Аргументы шаблона
От: 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[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.
Аргументы шаблона
От: Dr.Offset  
Дата: 31.10.07 09:32
Оценка:
Компилирую этот код в mingw 3.4.5:

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

Компиляция проходит без ошибок и предупреждений. Справедлив ли такой код, и если да, то как правильно инстанцировать такой шаблон?
Re[2]: Аргументы шаблона
От: Lorenzo_LAMAS  
Дата: 31.10.07 09:52
Оценка:
Кстати, чтобы мой пример скомпилился, для mingw придется объявления классов перед шаблоном поместить
А вижуалу и это не помогает.
Of course, the code must be complete enough to compile and link.
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[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]: Аргументы шаблона
От: 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.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.