Надеюсь, что название имеет смысл. Я, вероятно, скучаю по лексике, чтобы выразить ее правильно.C++ динамическое понижение к шаблону класса с шаблоном шаблона, являющимся шаблоном класса или шаблоном псевдонима
Ну, пример, вероятно, будет более понятным.
Проблема для меня: динамическое понижение возвращает 0 во время выполнения в некоторых из следующих случаев (написано в комментариях). Я хотел бы знать, правильное ли поведение (с использованием C++ 11), и почему, и что я могу сделать, чтобы он работал. По-видимому, Templated и A :: A_templated рассматриваются как разные классы, несмотря на то, что они определены как идентичные, используя псевдоним «использование». Проблема не возникает для простого алиаса typedef.
template <class T>
class Templated {};
class A {
public :
typedef int A_Type;
template <class T>
using A_Templated = Templated<T>;
};
class Test_base {
public :
Test_base() {}
virtual void foo()=0;
};
template <class T>
class Test_Type : public Test_base {
public :
Test_Type() {}
void foo() {}
};
template < template <class T> class TT >
class Test_Templated : public Test_base {
public :
Test_Templated() {}
void foo() {}
};
int main() {
Test_base* test;
test = new Test_Type<int>;
std::cout << dynamic_cast< Test_Type<int>* >(test) << std::endl;//-->ok
std::cout << dynamic_cast< Test_Type<A::A_Type>* >(test) << std::endl;//-->ok
test = new Test_Templated<Templated>;
std::cout << dynamic_cast< Test_Templated<Templated>* >(test) << std::endl;//-->ok
std::cout << dynamic_cast< Test_Templated<A::A_Templated>* >(test) << std::endl;//--> returns 0 !
test = new Test_Templated<A::A_Templated>;
std::cout << dynamic_cast< Test_Templated<A::A_Templated>* >(test) << std::endl;//-->ok
std::cout << dynamic_cast< Test_Templated<Templated>* >(test) << std::endl;//--> returns 0 !
}
Я предлагаю другой способ, чтобы увидеть проблему, это, вероятно, более ясным. Я столкнулся с этим, пытаясь избежать приведенного выше примера. Следующий пример в основном говорит о том, что указал Богдан. Я очень расстраиваю тот факт, что компилятор не может решить Templated with Templated_alias. Мне интересно, существует ли опция компиляции, которая может сортировать разрешение типа силы через псевдонимы шаблонов.
template <class T>
class Templated {};
template <class T>
using Templated_alias = Templated<T>;
template < template <class T> class TT >
class B;
template <>
class B<Templated> {
public :
void foo(Templated<int> _arg) {}
};
int main() {
B<Templated> b1;
b1.foo(Templated<int>());
b1.foo(Templated_alias<int>());//compiles => Templated_alias<int> is equivalent to Templated<int>
B<Templated_alias> b2;//Compilation error: Implicit instantiation of undefined template B<Templated_alias>
//which means: Templated_alias is not equivalent to Templated
}
Благодаря трюка Богдана, и после того, как какой-нибудь носовым кровотечением, мне удалось найти какое-то решение. Идея заключается в создании класса, отвечающего за «фильтрацию» потенциальных псевдонимов классов шаблонов. Он нуждается в одной спецификации для каждого класса шаблона, который должен быть «отфильтрован». Основным недостатком метода является то, что фильтрация, таким образом, должна использоваться везде, где классы шаблонов используются в качестве параметров шаблона, чтобы быть последовательными.
//Classes to be dealt with
template <class T>
class Templated {};
template <class T>
class Templated2 {};
template <class T>
using Templated_alias = Templated<T>;
class A_base {
virtual void foo()=0;
};
template <template <class T> class TT>
class A : public A_base {
void foo() {}
};
//Here starts the trick definition
template<template<class> class TT1, template<class> class TT2>
using is_same_template_t = typename std::is_same<TT1<int>, TT2<int> >::type;
//Template Template aliasing
template < template <class T> class TT >
class TT_aliasing {
public :
template <class T>
using Class_T = TT<T>;
};
//Template Template Alias Filtering
template < template <class T> class TT, class = std::true_type>
class TT_AF {
public :
template <class T>
using Class_T = TT<T>;
};
template < template <class T> class TT >
class TT_AF<TT, is_same_template_t<TT, Templated> > : public TT_aliasing<Templated> {};
int main() {
A_base* a;
a = new A< TT_AF<Templated>::Class_T >();
std::cout << dynamic_cast< A< TT_AF<Templated>::Class_T >* >(a) << std::endl;
std::cout << dynamic_cast< A< TT_AF<Templated_alias>::Class_T >* >(a) << std::endl;
std::cout << dynamic_cast< A< TT_AF<Templated2>::Class_T >* >(a) << std::endl;
std::cout << "---------------" << std::endl;
a = new A< TT_AF<Templated_alias>::Class_T >();
std::cout << dynamic_cast< A< TT_AF<Templated>::Class_T >* >(a) << std::endl;
std::cout << dynamic_cast< A< TT_AF<Templated_alias>::Class_T >* >(a) << std::endl;
std::cout << dynamic_cast< A< TT_AF<Templated2>::Class_T >* >(a) << std::endl;
std::cout << "---------------" << std::endl;
a = new A< TT_AF<Templated2>::Class_T >();
std::cout << dynamic_cast< A< TT_AF<Templated>::Class_T >* >(a) << std::endl;
std::cout << dynamic_cast< A< TT_AF<Templated_alias>::Class_T >* >(a) << std::endl;
std::cout << dynamic_cast< A< TT_AF<Templated2>::Class_T >* >(a) << std::endl;
A< TT_AF<Templated>::Class_T > a1;
A< TT_AF<Templated_alias>::Class_T > a2;
a1 = a2;
A< TT_AF<Templated2>::Class_T > a3;
//a1 = a3;//no viable overloaded '='
}
Выход дает:
0x600000014ba0
0x600000014ba0
0x0
---------------
0x600000014bb0
0x600000014bb0
0x0
---------------
0x0
0x0
0x600000014bc0
После использования вышеуказанной цели. Я столкнулся с разными проблемами. Не может быть абсолютно уверен, что это связано, но это очень вероятно. Компилятор, похоже, пытается правильно построить «динамическую таблицу». Я задал эту проблему на C++ what can make type_info::hash_code differs for two (supposedly) same objects Может быть, я плохой, но на данный момент я бы не рекомендовал использовать трюк с Clang 3.1.
Будьте более ясны относительно _ _ детали. Ошибки времени выполнения, ошибки компилятора? Пожалуйста, разместите их все дословно в своем вопросе. –
сделано редактирование, подумал, что пример достаточно ясен – brahmin
Работы нормально для меня. См. Http://ideone.com/rFTnDd. Какая у вас платформа? –