#c #templates #casting
#c #шаблоны #Кастинг
Вопрос:
Я создал список типов. Затем я создаю класс, используя шаблон, передающий список типов. Когда я вызываю функцию print класса с некоторыми не указанными типами, они преобразуются. Как я могу обеспечить соблюдение точного типа во время компиляции? Итак, если я использую тип, не указанный в списке, я получаю ошибку компилятора. Спасибо.
template <class T, class U>
struct Typelist
{
typedef T Head;
typedef U Tail;
};
class NullType
{
};
typedef Typelist<int,Typelist<float,Typelist<char*,NullType> > > UsableTypes;
template<class T>
class MyClass
{
public:
void print(T::Head _Value) { std::cout << _Value; }
void print(T::Tail::Head _Value) { std::cout << _Value; }
void print(T::Tail::Tail::Head _Value) { std::cout << _Value; }
private:
};
MyClass<UsableTypes> testclass;
void TestMyClass()
{
int int_val = 100000;
float flt_val = 0.1f;
char* char_val = "Hi";
short short_val = 10;
std::string str_val = "Hello";
testclass.print( int_val ); // OK 8-)
std::cout << endl;
testclass.print( flt_val ); // OK 8-)
std::cout << endl;
testclass.print( char_val ); // OK 8-)
std::cout << endl;
testclass.print( short_val); // this compiles OK and works ??? 8-(
std::cout << endl;
testclass.print( str_val ); // compile error 8-)
std::cout << endl;
}
@Kerrek SB: Привет, я думал, это поможет мне со следующим шагом, который заключался в создании функции печати в зависимости от содержимого t_list, типов и количества типов. Но я изо всех сил пытаюсь разделить обработку во время компиляции и обработку во время выполнения. Что я пытаюсь сделать, так это создать функцию печати для каждого типа в списке. Итак, если список имеет два типа, будут созданы две функции печати, а если типов пять, то будут созданы пять функций печати, по одной для каждого типа.
Когда я делаю это:
typedef Typelist<int,Typelist<float,Typelist<char*,NullType> > > UsableTypes;
MyClass<UsableTypes> newclass
Создает ли это три экземпляра MyClass по одному для каждого типа в списке или создает один экземпляр, и я должен создать функцию печати для каждого типа?
Я чувствую, что у меня почти все блоки в голове, но просто не могу соединить их вместе. Любая помощь, которую вы можете предложить, будет принята с благодарностью. Спасибо.
Комментарии:
1. Ваша
Ответ №1:
Добавьте шаблон частной функции
template<typename T> void print(T);
для которого не требуется реализация. Это должно перехватывать все типы, для которых не существует явной печати, и, поскольку она является частной, это выдаст сообщение об ошибке.
Комментарии:
1. Спасибо, что решили мою проблему. Это кажется очевидным, когда указано 🙂
Ответ №2:
Вам пришлось бы превратить вашу print
функцию в шаблон, а затем проверить, совпадают ли типы:
template <typename U>
void print(const U amp; u)
{
// use std::is_same<typename std::decay<T::Head>::type, typename std::decay<U>::type>::value
}
Здесь я ворую is_same
и decay
из <type_traits>
, но если у вас нет C 11, вы можете либо взять их из TR1 или Boost, либо просто написать их самостоятельно, поскольку это очень простые классы-модификаторы типа.
Условное обозначение лучше всего использовать в static_assert
, что является еще одной особенностью C 11, но для C 98/03 существуют аналогичные конструкции, которые при определенных условиях приводят к ошибке во время компиляции.
Комментарии:
1. @sehe: это действительно встречалось на моем пути раньше 🙂
2. Спасибо, это помогло мне с моей следующей проблемой, заставив создавать функции печати для списков типов различного размера.
Ответ №3:
Вы могли бы использовать свои аргументы по неконстантной ссылке, принудительно приводя их к одному и тому же типу. Однако вы больше не можете использовать его с постоянными переменными или литералами.
Комментарии:
1. Спасибо, теперь я начинаю смотреть на эти проблемы под другим углом.