Reputation: 20800
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
Upvotes: 1
Views: 4346
Reputation: 73580
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) {...};
Upvotes: 0
Reputation: 5449
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
Upvotes: 2
Reputation:
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.
Upvotes: 1
Reputation: 361762
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
.
Upvotes: 7
Reputation: 6357
Give a try to BOOST_STRONG_TYPEDEF which is avalailabel in Boost.Serialization.
Upvotes: 0