简体   繁体   中英

Function overload with same parameter type in C++

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

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 .

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

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.

尝试使用BOOST_STRONG_TYPEDEF,它是Boost.Serialization中的aavaailabel。

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) {...};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM