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

4
  • typedef create an alias of T. Even this fills namespace Commented May 31, 2012 at 9: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)? Commented May 31, 2012 at 9: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 Commented May 31, 2012 at 9: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. Commented May 31, 2012 at 9:24

5 Answers 5

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.

Sign up to request clarification or add additional context in comments.

Comments

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

1 Comment

+1 for this is not what typedefs should be used for.This simplest and most intuitive solution.
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.

Comments

0

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

1 Comment

That would use a macro to fill the namespace with new classes. :-)
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) {...};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.