Managing my own archive system, I have the following virtual functions:
virtual void OutputArchive::save_unsigned_long_int(unsigned long int i);
virtual void OuptutArchive::save_unsigned_long_long_int(unsigned long long int i);
virtual void InputArchive::load_unsigned_long_int(unsigned long int& i);
virtual void InputArchive::load_unsigned_long_long_int(unsigned long long int& i);
Then, for some reason I also have to manage type std::size_t
, which can be different depending on the compiler. For example, with gcc on Linux 64-bits, std::size_t
is a unsigned long int
, but with intel on Windows 64-bits, std::size_t
is a unsigned long long int
. In a first approach, I wrote something like that:
void OutputArchive::save_size_t(std::size_t i)
{
if(boost::is_same<std::size_t,unsigned long int>::value)
this->save_unsigned_long_int((unsigned long int)i);
else if(boost::is_same<std::size_t,unsigned long long int>::value)
this->save_unsigned_long_long_int((unsigned long long int)i);
else { /* error management */ }
}
But, I'm not happy with that: it's ugly, only one line can ever be executed, the type is known at compilation time. I suppose it's possible to do better with preprocessing, but I don't know how to start this. Any help is welcome.
Note: I don't use C++11 for compatibility reason, but I use Boost.
The preprocessor knows nothing about types. Or scopes. Or anything which involves the semantics of the program. All the preprocessor can deal with are tokens, which are just sequences of characters corresponding to a small set of lexical rules.
In short, it is true that the type is known at compile-time, but not during the translation phases corresponding to the preprocessor. C++ uses type information at compile-time to determine the appropriate overloaded function, and to deduce the correct template definition. Either of those could be an appropriate solution to your problem.
It's possibly worth noting that the C++ standard only requires that
size_t
be "an unsigned integer type". It does not need to be a standard unsigned integer type (see §3.9.1p1), so it is possible thatsize_t
is neitherunsigned int
,unsigned long int
norunsigned long long int
. (A similar comment applies toptrdiff_t
and signed integer types.)