c++c++11overloadingtypedef

Using aliases for strictly typing function parameters


It's possible to use an alias to change the literal signature of a function:

using String = std::string;

void Print(String s) { ... };

But this doesn't disallow calling Print with a std::string:

Print(std::string{"Hello world"}); // Still works

This makes sense -- an alias is strictly for simplifying a name for a type, it does not define a new type.

Besides subclassing, which is not a good idea, is there a mechanism by which it's possible to achieve strict typing by name for function parameters? An immediate consequence of this is that this would be possible as well:

using StringA = std::string;
using StringB = std::string;

void Print(StringA s) { ... };
void Print(StringB s) { ... };

Print(StringA{"Hello world"});
Print(StringB{"Hi everyone"});

My current solution is to define simple wrapper classes that hold the type I want to alias as a member. This isn't ideal because it requires duplicating the interface for the member class into the wrapper, something that isn't necessary when using an alias.


Solution

  • The standard makes typedefs and alias a synonym for another type and not a new type:

    7.1.3/1: A name declared with the typedef specifier becomes a typedef-name. Within the scope of its declaration, a typedef-name is syntactically equivalent to a keyword and names the type associated with the identifier in the way described in Clause 8. A typedef-name is thus a synonym for another type. A typedef-name does not introduce a new type the way a class declaration or enum declaration does.

    and

    7.1.3/2: A typedef-name can also be introduced by an alias-declaration. The identifier following the using keyword becomes a typedef-name. It has the same semantics as if it were introduced by the typedef specifier. In particular, it does not define a new type and it shall not appear in the type-id.

    So unfortunately, you'll have to continue to use your class wrapper to introduce different types and being able to overload function on this base.