If I have a widely-used class template called Foo
that I want to rename to Bar
without having to update all of its users atomically, then up until C 17 I could simply use a type alias:
template <typename T>
class Bar {
public:
// Create a Bar from a T value.
explicit Bar(T value);
};
// An older name for this class, for compatibility with callers that haven't
// yet been updated.
template <typename T>
using Foo = Bar<T>;
This is very useful when working in a large, distributed codebase. However as of C 17 this seems to be broken by class template argument deduction guides. For example, if this line exists:
template <typename T>
explicit Foo(T) -> Foo<T>;
then the obvious thing to do when renaming the class is to change the Foo
s in the deduction guide to Bar
s:
template <typename T>
explicit Bar(T) -> Bar<T>;
But now the expression Foo(17)
in a random caller, which used to be legal, is an error:
test.cc:42:21: error: alias template 'Foo' requires template arguments; argument deduction only allowed for class templates
static_cast<void>(Foo(17));
^
test.cc:34:1: note: template is declared here
using Foo = Bar<T>;
^
Is there any easy and general way to give a class with deduction guides two simultaneous names in a fully compatible way? The best I can think of is defining the class's public API twice under two names, with conversion operators, but this is far from easy and general.
CodePudding user response:
Your problem is exactly what P1814R0: Wording for Class Template Argument Deduction for Alias Templates
wants to solve, that is to say, in C 20, you only need to add deduction guides for Bar
to make the following program well-formed:
template <typename T>
class Bar {
public:
// Create a Bar from a T value.
explicit Bar(T value);
};
// An older name for this class, for compatibility with callers that haven't
// yet been updated.
template <typename T>
using Foo = Bar<T>;
template <typename T>
explicit Bar(T) -> Bar<T>;
int main() {
Bar bar(42);
Foo foo(42); // well-formed
}
But since it is a C 20 feature, there is currently no solution in C 17.
CodePudding user response:
Have you tried to define a macro?
#define Foo Bar;
(Personally I'd find it confusing with multiple names for same implementation, but I'm not you.)
Sorry I can't test at the moment, but I hope it works!