Вот простейший пример.
struct TestSel
{
template <typename T>
struct bind_ { typedef T type; };
};
template <typename SomeSel>
struct test
{
typedef typename SomeSel::bind_<int>::type sel_t; //fatal error C1001: INTERNAL COMPILER ERROR
};
int main()
{
test<TestSel> test1;
}
Выдаёт INTERNAL COMPILER ERROR при попытке получить тип из селектора.
Как сделать на этом гадстве селектор типа???
Здравствуйте, eaglus, Вы писали:
E>Вот простейший пример.
E>E>struct TestSel
E>{
E> template <typename T>
E> struct bind_ { typedef T type; };
E>};
E>template <typename SomeSel>
E>struct test
E>{
E> typedef typename SomeSel::bind_<int>::type sel_t; //fatal error C1001: INTERNAL COMPILER ERROR
E>};
E>int main()
E>{
E> test<TestSel> test1;
E>}
E>
E>Выдаёт INTERNAL COMPILER ERROR при попытке получить тип из селектора.
E>Как сделать на этом гадстве селектор типа???
Попробуй посмотреть
http://www.boost.org/libs/mpl/doc/index.html.
Если я не ошибаюсь, там можно найти решение этой проблемы.
Здравствуйте, eaglus,
Может быть вот так
struct TestSel
{
template <typename T>
struct bind_ { typedef T type; };
};
template <typename SomeSel>
struct test
{
int a;
typedef typename TestSel::bind_<int>::type sel_t;
};
int main()
{
test<TestSel> test1;
}
Здравствуйте, FoolS.Top, Вы писали:
FT>Здравствуйте, eaglus,
FT>Может быть, вот так
Так здесь вообще никакого селектора нет.
Понятно, что если написать конкретный тип TestSel вместо селектора SomeSel, то всё работает.
Но мне-то надо получить тип из генератора, который я передаю аргументом шаблона.
FT>FT>struct TestSel
FT>{
FT> template <typename T>
FT> struct bind_ { typedef T type; };
FT>};
FT>template <typename SomeSel>
FT>struct test
FT>{
FT> int a;
FT> typedef typename TestSel::bind_<int>::type sel_t;
FT>};
FT>int main()
FT>{
FT> test<TestSel> test1;
FT>}
FT>
Здравствуйте, eaglus, Вы писали:
<>
А откуда компилятор догадается, что SomeSel::bind_ — это шаблон, и соответственно, < > это угловые скобки, а не больше-меньше?
Правильно так:
typedef typename SomeSel::template bind_<int>::type sel_t;
Впрочем, на VC6 тебя это не спасёт.
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, eaglus, Вы писали:
К><>
К>А откуда компилятор догадается, что SomeSel::bind_ — это шаблон, и соответственно, < > это угловые скобки, а не больше-меньше?
К>Правильно так:
К>К>typedef typename SomeSel::template bind_<int>::type sel_t;
К>
К>Впрочем, на VC6 тебя это не спасёт.
Да, не спасло...
Как же всё-таки генератор типов сделать?
Хочется как в boost graph library:
struct listS
{
template <class T>
struct bind_ { typedef std::list<T> type; };
};
template <class EdgeData, class EdgesContSel>
struct graph
{
typedef typename EdgesContSel::template bind_<EdgeData>::type edges_cont_t;
edges_cont_t m_edges;
};
int main()
{
graph<double, listS> my_list_graph;
graph<double, vectorS> my_vector_graph;
}
Здравствуйте, eaglus, Вы писали:
E>Вот простейший пример.
E>E>struct TestSel
E>{
E> template <typename T>
E> struct bind_ { typedef T type; };
E>};
E>template <typename SomeSel>
E>struct test
E>{
E> typedef typename SomeSel::bind_<int>::type sel_t; //fatal error C1001: INTERNAL COMPILER ERROR
E>};
E>int main()
E>{
E> test<TestSel> test1;
E>}
E>
E>Выдаёт INTERNAL COMPILER ERROR при попытке получить тип из селектора.
E>Как сделать на этом гадстве селектор типа???
А не знает ли кто, как этот трюк по-научному называется?
Я его спёр из boost graph library.
Попробовал другой способ генерации типа по шаблону, со специализациями.
gcc-mingw-3.2 компилит без ворнингов, VS8 тоже, VS7.3 (2003) тоже.
VC6 + SP5 дохнет. Где, показано в примере.
То есть, уже не INTERNAL ERROR, но тип из шаблонной структуры нам всё равно не дают.
Может, кто-то знает, как это гадство обойти, и вообще, как это будет компилиться на других компиляторах (сановском, gcc 2.95, и ещё какие там есть)...
Если забить на VC6, тогда можно считать этот код портабельным или нет?
#include <vector>
#include <list>
#include <iostream>
using namespace std;
struct empty_type {};
struct vecS {};
struct listS {};
template <class Sel> struct ContTraits
{
template <class T> struct bind_
{
typedef empty_type type;
};
};
template <> struct ContTraits<listS>
{
template <class T> struct bind_
{
typedef std::list<T> type;
};
};
template <class EdgeData, class EdgeContSel>
class Graph {
struct stored_edge {
int v; int s; EdgeData data;
stored_edge(const int v_, const int s_, const EdgeData& data_)
: v(v_), s(s_), data(data_) { }
stored_edge(const stored_edge& rhs) : v(rhs.v), s(rhs.s), data(rhs.data)
{ }
};
typedef typename ContTraits<EdgeContSel>::template bind_<stored_edge> ste_cont;
typename ste_cont::type m_edge_store;/// VC6.5 error C2039: 'type' : is not a member of '`global namespace''
//И потом тут кучей:
//error C2501: 'm_edge_store' : missing storage-class or type specifiers
//fatal error C1004: unexpected end of file found
//see reference to class template instantiation 'Graph<double,struct listS>' being compiled
public:
void add_edge() {
m_edge_store.push_back(stored_edge(1, 2, 3.0));
}
};
typedef Graph<double, listS> MyGraph;
int main()
{
MyGraph gr;
gr.add_edge();
}