Возможно ли в С++ проверить тип, переданный в функцию шаблона? Например:
template <typename T>
void Foo()
{
if (typeof(SomeClass) == T)
...;
else if (typeof(SomeClass2) == T)
...;
}
Возможно ли в С++ проверить тип, переданный в функцию шаблона? Например:
template <typename T>
void Foo()
{
if (typeof(SomeClass) == T)
...;
else if (typeof(SomeClass2) == T)
...;
}
Да, это... но он, вероятно, не будет работать так, как вы ожидаете.
template < typename T >
void foo()
{
if (is_same<T,SomeClass>::value) ...;
else if (is_same<T,SomeClass2>::value) ...;
}
Вы можете получить is_same
из std::
или boost::
в зависимости от вашего желания/компилятора. Первый только в С++ 0x.
Проблема связана с тем, что находится в ...
. Если вы ожидаете, что сможете сделать какой-либо вызов функции конкретным для этих типов внутри foo, вы, к сожалению, ошибаетесь. Ошибка компилятора приведет даже к тому, что этот раздел кода никогда не будет запущен, когда вы передадите то, что не подчиняется ожидаемому интерфейсу.
Чтобы решить эту проблему, вам нужно сделать что-то совсем другое. Я бы рекомендовал отправку тегов:
struct v1_tag {};
struct v2_tag {};
template < typename T > struct someclass_version_tag;
template < > struct someclass_version_tag<SomeClass> { typedef v1_tag type; };
template < > struct someclass_version_tag<SomeClass2> { typedef v2_tag type; };
void foo(v1_tag) { ... }
void foo(v2_tag) { ... }
template < typename T > void foo()
{
typedef typename someclass_version_tag<T>::type tag;
foo(tag());
}
Обратите внимание, что вы не будете страдать от накладных расходов во время выполнения - полиморфизм здесь и при включенной оптимизации должны привести к тому же или даже меньшему размеру кода и скорости (хотя вы не должны беспокоиться об этом в любом случае, пока вы не запустите профилировщик).
Если вы хотите сделать что-то конкретное, основанное на типе, специализируйте шаблон:
template <typename T>
void Foo() { }
template <>
void Foo<SomeClass>() { }
template <>
void Foo<SomeClass2>() { }
// etc.
(На самом деле, вы не хотите специализировать шаблон функции, это только для изложения. Вам нужно либо перегрузить шаблон, либо добавить его в специализированный шаблон шаблона. как избежать специализированных шаблонов функций, читать Herb Sutter Почему не специализировать шаблоны функций?)
Да. Вам придется использовать свойства типа. Например:
#include <boost/type_traits/is_same.hpp>
template <typename T>
void Foo ()
{
if ((boost::is_same<T, SomeClass>::value))
...;
else if ((boost::is_same<T, SomeClass2>::value))
...;
}
В зависимости от того, чего вы пытаетесь достичь, использование специализация шаблона может быть намного лучшим выбором.
Кроме того, вы можете использовать enable_if/disable_if, чтобы условно включить/отключить определенные функции/методы. Объединение этого с типом признаков позволит, например, использовать одну функцию для одного набора типов и другую функцию для другого набора типов.
Нет, однако вы можете использовать частичную специализацию:
template<typename T>
struct Bar { static void foo(); };
template<typename T>
template<> inline void Bar<T>::foo() {
//generic
}
template<> inline void Bar<int>::foo() {
//stuff for int
}
template<> inline void Bar<QString>::foo() {
//QString
}
Изменить Да с характерными чертами, однако это действительно не нужно. Изменить 2 пример type_traits.
#include <type_traits>
template<typename T> void foo() {
using std::is_same;
if<is_same<T, T2>::value || is_same<T, T1>::value) {
/* stuff */
}
}