7

I have a template I want to specialize with two int types, one of them plain old int and another one is intptr_t. On 64 bit platform they have different sizes and I can do that with ease but on 32 bit both types are the same and compiler throws an error about redefinition. What can I do to fix it except for disabling one of definitions off with preprocessor?

Some code as an example:

template<typename T>
type * convert();

template<>
type * convert<int>() { return getProperIntType(sizeof(int)); }

template<>
type * convert<intptr_t>() { return getProperIntType(sizeof(intptr_t)); }

//this template can be specialized with non-integral types as well, 
// so I can't just use sizeof() as template parameter.
template<>
type * convert<void>() { return getProperVoidType(); }
Kirill V. Lyadvinsky
  • 97,037
  • 24
  • 136
  • 212
vava
  • 24,851
  • 11
  • 64
  • 79
  • What's wrong with something like `#if COMPILING_FOR_64_BIT_PLATFORM`? (Also, you need to fix the return types of the specializations.) – sbi May 25 '10 at 10:25
  • 1
    If you really want to do this using template magic, I suppose you could come up with something using some form of `enable_if` which only enables if `int` and `intptr_t` are not the same type. – sbi May 25 '10 at 10:45
  • Why do you need to explicitly specialise the template for each type? Why not just have one template for all types `T` which calls `getProperIntType(sizeof (T))`? If it's important to only handle integer types this way, you can hand off to a helper function using SFINAE (google that) but be warned: it's messy. – j_random_hacker May 25 '10 at 10:49
  • @sbi, nothing wrong with it except that is equally hard to get that to work reliably across different compilers and environments. And no, I don't have to fix return types, they are identical to all specializations :) – vava May 25 '10 at 11:49
  • @j_random_hacker: I suppose not all types can be treated alike (`getProperIntType()` vs. `getProperVoidType()`). Also note that the base template isn't even implemented. It might not be wanted to compile for types other than what it is specialized for. – sbi May 25 '10 at 14:24
  • @vava: Sorry for the brainfart regarding the return types. (I confused `type` with `T`.) Then what about `enable_if`. Wouldn't that work? – sbi May 25 '10 at 14:25
  • @sbi, yes, something like that should work. But unless I include `boost` (which I don't want to, bad enough I use C++ in C project) I would have to write quite a lot of code for it to work :) So I decided to settle with `#if INTPTR_MAX != INT32_MAX` for now. – vava May 25 '10 at 16:07

1 Answers1

2

What you're trying to achieve is fundamentally impossible: intptr_t is a typedef for int on 32 bit systems, so the compiler can't distinguish them. However, your example could be solved by just specializing the void case:

template<typename T>
type * convert() { return getProperIntType(sizeof(T)); }

template<>
type * convert<void>() { return getProperVoidType(); }
Ondergetekende
  • 1,065
  • 9
  • 22
  • Bad news then. As for your solution, I don't like that it is silently treating all new types as int. Although it can be solved with some kind of static assertion I guess. – vava May 25 '10 at 11:37