Re: Is run-time switching on type traits bad?
Daniel T. wrote:
In article <4bc64413$0$275$14726298@news.sunsite.dk>,
DeMarcus <use_my_alias_here@hotmail.com> wrote:
Hi,
Is run-time switching on type traits as bad as switching on class type?
(Sutter & Alexandrescu, C++ Coding Standards, Item 90 - Avoid type
switching)
I.e. should type traits be for compile time only?
A run-time example:
class VisitableInterface
{
public:
virtual ~VisitableInterface() {}
virtual void accept( Visitor& v ) const = 0;
virtual bool isPOD() const = 0;
};
template<typename T>
class SomeVisitable : public VisitableInterface
{
public:
SomeVisitable( const T& element ) : element_(element) {}
virtual void accept( Visitor& v ) const
{
...
}
virtual bool isPOD() const
{
return std::is_pod<T>::value;
}
private:
const T element_;
};
int main()
{
std::vector<VisitableInferface*> vec;
PodVisitor podVisitor;
ClassVisitor classVisitor;
for( auto i = vec.begin(); i != vec.end(); ++i )
{
if( (*i)->isPOD() )
(*i)->accept( podVisitor );
else
(*i)->accept( classVisitor );
}
}
You are breaking "tell don't ask" here. http://pragprog.com/articles/tell-dont-ask
However, when dealing with PODs you don't have a lot of choices in
the matter. Does it really need to be POD? Could you make two
SomeVisitable classes, one for PODs and the other for classes, with
compile time checking to make sure the correct one is
used? After all, when the programmer instantiates the template, he
knows whether the type he is passing is POD or not.
Good point, and thanks for the link.
I tried another compile time solution that looked like similar to this.
class SomeClass
{
public:
template<typename T>
inline void accept( const T& t )
{
privateAccept<T, std::is_pod<T>::value>( t );
}
private:
template<typename T, bool isPOD>
inline void privateAccept( const T& t ) {}
// Partial specialization for POD
template<typename T>
inline void privateAccept<T, true>( const T& t )
{
... do things when t is POD
}
// Partial specialization for non-POD
template<typename T>
inline void privateAccept<T, false>( const T& t )
{
... do things when t is non-POD
}
}
However, the language doesn't allow partial specialization on function
templates. My solution would be, as you suggested, to go up a bit in the
hierarchy and call two different functions depending on the type;
acceptPOD( const T& t )
acceptNonPOD( const T& t )
However, it feels that calling two different functions reveals
implementations details. The caller should not know that it is important
what the type is.
My last solution is to make one function for each POD, they are not that
many.
void accept( int arg )
void accept( char arg )
void accept( float arg )
.... etc ...
// and for the non-pod
template<typename T>
void accept( T t )
/Daniel
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]