可能重复:
Is it possible to write a C++ template to check for a function's existence?
在JavaScript等语言中,您可以检查是否存在属性
// javascript
if( object['property'] ) // do something
在C ++中,我想根据类型T
是否具有某种属性来调节编译。这可能吗?
template <typename T>
class IntFoo
{
T container ;
public:
void add( int val )
{
// This doesn't work, but it shows what I'm trying to do.
// if the container has a .push_front method/member, use it,
// otherwise, use a .push_back method.
#ifdef container.push_front
container.push_front( val ) ;
#else
container.push_back( val ) ;
#endif
}
void print()
{
for( typename T::iterator iter = container.begin() ; iter != container.end() ; ++iter )
printf( "%d ", *iter ) ;
puts( "\n--end" ) ;
}
} ;
int main()
{
// what ends up happening is
// these 2 have the same result (500, 200 --end).
IntFoo< vector<int> > intfoo;
intfoo.add( 500 ) ;
intfoo.add( 200 ) ;
intfoo.print() ;
// expected that the LIST has (200, 500 --end)
IntFoo< list<int> > listfoo ;
listfoo.add( 500 ) ;
listfoo.add( 200 ) ; // it always calls .push_back
listfoo.print();
}
答案 0 :(得分:4)
以下示例演示了一种可以使用的技术(在C ++ 11中,使用SFINAE for expressions):
typedef char no;
typedef no (&yes)[2];
no detect_push_front( ... );
template < class C >
auto detect_push_front( C &c ) -> typename std::conditional< false, decltype( c.push_front( std::declval< typename C::value_type >() ) ), yes >::type;
template < class C >
struct has_push_front : std::integral_constant< bool, sizeof( detect_push_front( std::declval< C & >() ) ) == sizeof( yes ) > {};
template < class C >
void add( C &c, typename C::value_type v, std::true_type )
{
c.push_front( v );
}
template < class C >
void add( C &c, typename C::value_type v, std::false_type )
{
c.push_back( v );
}
template < class C >
void add( C &c, typename C::value_type v )
{
add( c, v, has_push_front< C >() );
}
int main()
{
std::vector< int > v;
add( v, 0 );
add( v, 1 );
add( v, 2 );
std::copy( v.begin(), v.end(), std::ostream_iterator< int >( std::cout, " " ) );
std::cout << '\n';
std::list< int > l;
add( l, 0 );
add( l, 1 );
add( l, 2 );
std::copy( l.begin(), l.end(), std::ostream_iterator< int >( std::cout, " " ) );
std::cout << '\n';
}
输出:
0 1 2
2 1 0
答案 1 :(得分:1)
据我所知,在C ++中实现“条件编译”的唯一方法是使用预处理器指令,例如ifdef
和ifndef
。我没有任何其他技术存在。
答案 2 :(得分:1)
你不能这样做,但你可以拥有像
这样的东西template<T,TT> void push_there(T& c,T& i) { c.push_back(i); }
对具有push_front
的容器类型进行部分特化。或者相反。