Detect std::size_t type at compilation time to call the right function

590 views Asked by At

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.

1

There are 1 answers

0
rici On

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 that size_t is neither unsigned int, unsigned long int nor unsigned long long int. (A similar comment applies to ptrdiff_t and signed integer types.)