1

I want to override a function with same parameter type, but with different logical meaning. I've tried something like:

class T
{
};

typedef T Age;
typedef T Height;
typedef T Weight;

void foo(Age a){}
void foo(Height a){}
void foo(Weight a){}

but I have build errors: error C2084: function 'void foo(Age)' already has a body

One solution would be:

class Age : public T{};
class Height : public T{};
class Weight : public T{};

but I don't want to fill my namespace with new classes only for this purpose.

How may I achieve this without using derived classes?

EDIT: My code is in a cpp file, I don't use headers. This is just a simple example. Full cpp content is here:

class T
{
};

typedef T Age;
typedef T Height;
typedef T Weight;

void foo(Age a){}
void foo(Height a){}
void foo(Weight a){}

int main()
{
    return 0;
}

Error message: .cpp(10): error C2084: function 'void foo(Age)' already has a body

Nawaz
  • 353,942
  • 115
  • 666
  • 851
Mircea Ispas
  • 20,260
  • 32
  • 123
  • 211
  • `typedef` create an alias of T. Even this fills namespace – Alessandro Pezzato May 31 '12 at 09:01
  • If you want new types, you just *have* to declare new types. A `typedef` just creates a new *name* for the same type. Suppose `T` is an `int` - how would the compiler resolve `foo(42)`? – Bo Persson May 31 '12 at 09:17
  • @BoPersson I would never call the functions with direct values. The functions are part of a serialization class and I need to serialize in different ways, depending on the file type, Path objects – Mircea Ispas May 31 '12 at 09:19
  • @Felics - No difference. In this case `typedef T Age;` is just a scoped version of `#define Age T`. A `typedef` doesn't create a new type, so it cannot be used in overloading. – Bo Persson May 31 '12 at 09:24

5 Answers5

7

You could use templates as:

//1. First define T as class template
template<typename U>
class T
{
 public:
    typedef U tag_type;  //you may need this to inspect the type
    //...
};

//2. then define some tags
struct tag_age{};
struct tag_height{};
struct tag_weight{};

//3. then define typedefs
typedef T<tag_age> Age;
typedef T<tag_height> Height;
typedef T<tag_weight> Weight;

//4. then function overloads
void foo(Age a){}
void foo(Height a){}
void foo(Weight a){}

In this way, each of the typedefs are different types, and cannot be implicitly converted into other types, unless you allow this functionality explicitly in the defintion of the class template T.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
2

I do not think this is an appropriate usage of typedefs - at least concering your example, maybe this is different in production code. However this is not what typedefs should be used for IMHO. You should rather name your variables and functions properly as they will do different logical stuff:

void doAge(T age);
void doHeight(T height);

UPDATE: Where are typedefs appropriate then?

In your case the solution would complicate the code, so it seems rather unsuitable. Typedefs should be used to simplify things. For an example see my answer to following question: Meaning of complex C syntax

Community
  • 1
  • 1
Alex
  • 5,240
  • 1
  • 31
  • 38
1

You're fundamentally on the wrong track. Change the name of the actual parameter instead of its type. What you're doing makes no sense. A typedef basically uses the secondary simplified name to relate more to the code at hand, but it's just a programmer's shorthand, the compiler will still see T in all cases.

A number may represent age, a number of balls, length, height... In all cases, their logical use is different, but the fundamental datatypes used to encode their information remain the same. You shouldn't approach it this way.

0

Give a try to BOOST_STRONG_TYPEDEF which is avalailabel in Boost.Serialization.

Joel Falcou
  • 6,247
  • 1
  • 17
  • 34
0

You can use tags to do this

class T{};

typedef T Age;
typedef T Height;
typedef T Weight;

struct age_tag {};
struct height_tag {};
struct weight_tag {};

void foo(Age a, age_tag ){...}
void foo(Height h, height_tag ){...}
void foo(Weight a, weight_tag ){...}

template<typename TAG> void bar(T t);
template<> void bar<age_tag>(Age a) {...};
template<> void bar<height_tag>(Height h) {...};
template<> void bar<weight_tag>(Weight a) {...};
Michael Anderson
  • 70,661
  • 7
  • 134
  • 187