Reputation: 2124
Suppose the following types:
enum class MyEnum1 {};
enum class MyEnum2 {};
typedef struct MyStruct1 {};
typedef struct MyStruct2 {};
and the following (stupid) conversions:
MyEnum1 convert_to_MyEnum2(MyEnum2 e) { return MyEnum1(); }
MyEnum2 convert_to_MyEnum1(MyEnum1 e) { return MyEnum2(); }
MyStruct1 convert_to_MyStruct1(MyStruct2 s) { return MyStruct1(); }
MyStruct2 convert_to_MyStruct2(MyStruct1 s) { return MyStruct2(); }
I want to have a single convert function that takes a single type and converts it to another.
Now, since the functions always accept a single different type and are not only different by the return type, I can obviously change all the convert_to_*
into a convert
and overload this function with all the possibilities I have.
But, I don't like the idea of having user write something like:
auto e1 = convert(e2);
Foo(convert(e1));
I want the code to be readable so I was thinking of having something like:
//make all "convert" overloads private and only expose this function
template<typename To, typename From>
To convert_to(From from)
{
return convert(from);
}
this way the code will be:
auto e1 = convert_to<MyEnum1>(e2);
Foo(convert_to<MyEnum2>(e1));
1- Is it possible to avoid the convert
overload but still use some sort of single entry point \ single function name to achieve what I want? (i.e find some usage to existing convert_to_x
)
2- I understand this is more code-review related but what is the recommended way (if such exist) to this issue?
Upvotes: 0
Views: 3629
Reputation: 863
Yes, a conversion function covering multiple types with a single name can be implemented with template specialization.
enum class MyEnum1 {};
enum class MyEnum2 {};
struct MyStruct1 {};
struct MyStruct2 {};
// Unimplemented general fall-back case.
// Note: there are more civilized ways to issue a compilation error...
template<typename To, typename From>
To convert_to(From from) { return To::unimplemented_conversion; }
template<> MyEnum1 convert_to(MyEnum2 from) { return MyEnum1(); }
template<> MyEnum2 convert_to(MyEnum1 from) { return MyEnum2(); }
template<> MyStruct1 convert_to(MyStruct2 from) { return MyStruct1(); }
template<> MyStruct2 convert_to(MyStruct1 from) { return MyStruct2(); }
int main()
{
MyEnum2 e2 = convert_to<MyEnum2>(MyEnum1());
MyEnum1 e1 = convert_to<MyEnum1>(e2);
// MyStruct1 s1 = convert_to<MyStruct1>(e2); unimplemented conversion
return 0;
}
Upvotes: 2