3

如果我有一个广泛使用的类模板Foo,我想重命名它Bar而不必自动更新其所有用户,那么在 C++17 之前我可以简单地使用类型别名:

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>;

在大型分布式代码库中工作时,这非常有用。然而,从 C++17 开始,这似乎被类模板参数推导指南所打破。例如,如果此行存在:

template <typename T>
explicit Foo(T) -> Foo<T>;

那么重命名类时最明显的事情就是将Foo演绎指南中的 s 更改为Bars:

template <typename T>
explicit Bar(T) -> Bar<T>;

但是现在在Foo(17)以前合法的随机调用者中的表达式是错误的:

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>;
^

是否有任何简单而通用的方法可以以完全兼容的方式为具有演绎指导的课程提供两个同时名称?我能想到的最好的方法是使用转换运算符在两个名称下定义类的公共 API 两次,但这远非简单和通用。

4

2 回答 2

5

你的问题正是P1814R0: Wording for Class Template Argument Deduction for Alias Templates 想要解决的问题,也就是说在 C++20 中,你只需要添加 deduction guides forBar就可以使下面的程序格式正确:

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
}

演示。

但由于是 C++20 的特性,目前 C++17 中没有解决方案。

于 2021-09-27T07:16:06.133 回答
0

您是否尝试过定义宏?

#define Foo Bar;

(就个人而言,我会发现它与同一实现的多个名称混淆,但我不是你。)

抱歉,我目前无法测试,但我希望它有效!

于 2021-09-27T07:12:25.493 回答