I frequently use the template class shown in the code example to make up new types that prevent me from passing wrong arguments, arguments in wrong order and to document the meaning of the arguments. See number (2) in the code example.
But there is one thing that is a little bit of a nuisance: I can´t use this class for reference types (see number (3) in the code example). Of course that doesn´t work, since reference collapsing is making my to constructors ambiguous, thats why I disabled the T&& constructor (see number (1) in the code example) to make the example work. But that is – I hope – only the second best solution?
Question: Is there a way to use the StrongType class, keeping both constructors in case of a non reference types, without creating a special class like StrongTypeRef only for reference types?
The example compiles as it is. To see the error please enable number (1) by uncommenting it.
Thx in advance!
#include <iostream>
template <typename T, typename Parameter>
class StrongType
{
public:
explicit StrongType(T const& value) : value_(value) {}
// (1) explicit StrongType(T&& value) : value_(value) {}
T& get() { return value_; }
T const& get() const {return value_; }
private:
T value_;
};
// (2) works great
using Iteration = StrongType<int, struct IterationType>;
// (3) Not o.k.
using IterationRef = StrongType<int&, struct IterationRefType>;
void do_something1(Iteration k)
{
std::cout << k.get();
}
void do_something2(IterationRef k)
{
k.get() = 42;
}
int main(int argc, const char * argv[]) {
Iteration it1(5);
do_something1(it1);
int refed = 0;
IterationRef it2(refed);
do_something2(it2);
return 0;
}
If you use perfect forwarding, then it works:
Live example: http://coliru.stacked-crooked.com/a/a78cb4617961f3c9