Re: Conditional compilation oddity
On 08/10/2013 01:11 AM, ?? Tiib wrote:
... All compilers I know of (that implement
'static_assert') optimize that if and the contents of else part
away from resulting binary when you write it like that:
//////////////////////////////////////////////
#include <iostream>
static constexpr int value = 1;
int main()
{
std::cout << "value= " << value << std::endl;
static_assert( value == 1, "Value_Not_1" );
if (value == 1) // <- some compilers may issue silly warnings
// about condition being always true
{
std::cout << "value 1" << std::endl;
}
else
{
// <- some compilers may issue silly warnings
// about unreachable code
std::cout << "value NOT 1" << std::endl;
}
}
/////////////////////////////////////////////////
So you need to be more specific ... why you need conditional
compiling here? It only makes code harder to read.
Below is source code that illustrates how conditional compilation
would have been helpful for readability. The template method
T* NewGuy( T* ptr )
is to return an independent T ptr, either bay calling new T, or,
preferably, by calling the method ptr->newGuy(). When ptr is not
NULL, it is assumed that T::newGuy() exists.
// Use #f 1 for the One Template Method
// Use #f 0 for the Two Template Method
# if 1 /////////// One Template Method /////////////
// This implementation fails if T is an abstract class,
// even if the abstract pointer is not NULL. The error
// is at compile time.
template< typename T >
T* NewGuy( const T* ptr = nullptr )
{
if( nullptr == ptr )
{
return new T;
}
return ptr->newGuy();
}
# else ////////// Two Template Methods ///////////////
// This implementation works
#include "boost/type_traits.hpp"
#include "assert.h"
// Accepts only abstract classes
template< typename T >
typename std::enable_if< boost::is_abstract<T>::value,
T* >::type
NewGuy( const T* ptr )
{
assert( ptr != nullptr );
return ptr->newGuy();
}
// Accepts only concrete classes
template< typename T >
typename std::enable_if< !boost::is_abstract<T>::value,
T* >::type
NewGuy( const T* ptr = nullptr )
{
if( nullptr == ptr )
{
return new T;
}
return ptr->newGuy();
}
# endif ////////////////////////////////////////////
#include <memory>
struct B
{
virtual B* newGuy( void ) const = 0;
};
struct A : public B
{
A* newGuy( void ) const
{
return new A;
}
} a;
int main( int argc, char* argv[] )
{
// This fails with the One Template Method
std::unique_ptr<B> bp( NewGuy( (B*) &a ) );
return 0;
}