不要使用运行时,而要使用静态检查。
首先,定义这个宏:
#define HAS_MEMBER_VARIABLE( NEW_STRUCT, VAR ) \
template<typename T> struct NEW_STRUCT ; /* introduce member name "VAR" */ \
struct Derived : T, Fallback ; \
\
template<typename C, C> struct ChT; \
\
template<typename C> static char (&f(ChT<int Fallback::*, &C::VAR>*))[1]; \
template<typename C> static char (&f(...))[2]; \
\
static bool const value = sizeof(f<Derived>(0)) == 2; \
};
这段代码用于检查类中是否存在成员变量。
如果该变量存在,可以使用SFINAE执行某些操作,就像下一个示例中所示:
#include <iostream>
#define HAS_MEMBER_VARIABLE( NEW_STRUCT, VAR ) \
template<typename T> struct NEW_STRUCT { \
struct Fallback { int VAR; }; \
struct Derived : T, Fallback { }; \
\
template<typename C, C> struct ChT; \
\
template<typename C> static char (&f(ChT<int Fallback::*, &C::VAR>*))[1]; \
template<typename C> static char (&f(...))[2]; \
\
static bool const value = sizeof(f<Derived>(0)) == 2; \
};
HAS_MEMBER_VARIABLE( x_check, x )
struct A
{
int x;
};
struct B
{
float notX;
};
template< typename T, bool hasX = x_check<T>::value >
struct doX
{
static void foo( const T & t )
{
std::cout<<"type has x variable, and it's value is "<<t.x<<std::endl;
}
};
template< typename T >
struct doX< T, false >
{
static void foo( const T & )
{
std::cout<<"type has no x variable"<<std::endl;
}
};
template< typename T >
void doFoo( const T& t )
{
doX< T, x_check<T>::value >::foo( t );
};
int main()
{
A a; a.x = 6;
B b; b.notX = 3.6;
std::cout<<"Calling foo() on A : ";
doFoo( a );
std::cout<<"Calling foo() on B : ";
doFoo( b );
}
bool has_material(Voxel&)
,让子类的作者重载它或者使用 ADL 进行重载。如果它被内联并返回一个常量,特别是在 C++11 中将其设为constexpr
,那么优化器应该能够像使用类型特征一样高效地处理它。 - Steve Jessop