Reputation: 4233
I have the following overloaded functions:
float myFunc(Vector2D vec) {
Temp2D temp;
for (int i = 0; i < 10; i++) {
temp += computeTemp(vec, i);
}
return temp.compute_a_float();
}
float myFunc(Vector3D vec) {
Temp3D temp;
for (int i = 0; i < 10; i++) {
temp += computeTemp(vec, i);
}
return temp.compute_a_float();
}
float myFunc(Vector4D vec) {
Temp4D temp;
for (int i = 0; i < 10; i++) {
temp += computeTemp(vec, i);
}
return temp.compute_a_float();
}
where computeTemp is also overloaded for Vector2D, Vector3D, Vector4D:
Temp2D computeTemp(Vector2D, int);
Temp3D computeTemp(Vector3D, int);
Temp4D computeTemp(Vector4D, int);
To avoid code duplication, I have come up with the idea to add a layer of abstraction:
template<typename T0, typename T1>
float myFunc(T0 vec) {
T1 temp;
for (int i = 0; i < 10; i++) {
temp += computeTemp(vec, i);
}
return temp.compute_a_float();
}
float myFunc(Vector2D vec) {
return myFunc<Vector2D, Temp2D>(vec);
}
float myFunc(Vector3D vec) {
return myFunc<Vector3D, Temp3D>(vec);
}
float myFunc(Vector4D vec) {
return myFunc<Vector4D, Temp4D>(vec);
}
However, I want to know if it is possible to avoid an additional layer of abstraction and directly decide the type of variable temp
in myFunc
.
Upvotes: 3
Views: 113
Reputation: 172864
directly decide the type of variable
temp
inmyFunc
.
You can use decltype
to determine the type, e.g.
template<typename T0>
float myFunc(T0 vec) {
decltype(computeTemp(vec, 0)) temp;
for (int i = 0; i < 10; i++) {
temp += computeTemp(vec, i);
}
return temp.compute_a_float();
}
BTW,
1. Note that if computeTemp
returns by reference instead of return-by-value, the result type of decltype
would also be reference (to lvalue or rvalue, depending on how computeTemp
returns); you might need to use std::remove_reference
with decltype
to get the type you want.
2. The expression used for decltype
belongs to unevaluated expressions:
The operands of the four operators typeid, sizeof
, noexcept, and decltype (since C++11)
are expressions that are not evaluated (unless they are polymorphic glvalues and are the operands of typeid), since these operators only query the compile-time properties of their operands. Thus,std::size_t n = sizeof(std::cout << 42);
does not perform console output.
Upvotes: 7
Reputation: 66190
Or using auto
instead of decltype()
template <typename VT>
float myFunc(VT vec) {
auto temp = computeTemp(vec, 0);
for (int i = 1; i < 10; i++) {
temp += computeTemp(vec, i);
}
return temp.compute_a_float();
}
This starting from C++11 (same limit for decltype()
).
For C++98, the best I can imagine is the creation of a custom type traits to select the temp
type.
Something like [caution: code not tested]
template <typename>
struct tempType;
template <> struct tempType<Vector2D> { typedef Temp2D type; };
template <> struct tempType<Vector3D> { typedef Temp3D type; };
template <> struct tempType<Vector4D> { typedef Temp4D type; };
template <typename VT>
float myFunc(VT vec) {
typename tempType<VT>::type temp;
for (int i = 0; i < 10; i++) {
temp += computeTemp(vec, i);
}
return temp.compute_a_float();
}
Upvotes: 4