如何使用推导指南为 C++ class 模板提供两个兼容的名称?
How can I give two compatible names to a C++ class template with deduction guides?
如果我有一个名为 Foo
的广泛使用的 class 模板,我想将其重命名为 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 开始,这似乎被 class 模板参数推导指南打破了。例如,如果此行存在:
template <typename T>
explicit Foo(T) -> Foo<T>;
那么重命名 class 时最明显的事情就是将演绎指南中的 Foo
s 更改为 Bar
s:
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>;
^
是否有任何简单和通用的方法以完全兼容的方式给出带有推导的 class 两个同时出现的名称? 我能想到的最好的方法是定义class 的 public API 两次在两个名称下,带有转换运算符,但这远非简单和通用。
你试过定义宏吗?
#define Foo Bar;
(就我个人而言,我发现它会混淆同一实现的多个名称,但我不是你。)
对不起,我现在无法测试,但我希望它有效!
你的问题正是P1814R0: Wording for Class Template Argument Deduction for Alias Templates
想要求解,也就是说,在C++20中,只需要为Bar
加上推导导数,就可以使下面的程序合式:
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中没有解决方案。
如果我有一个名为 Foo
的广泛使用的 class 模板,我想将其重命名为 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 开始,这似乎被 class 模板参数推导指南打破了。例如,如果此行存在:
template <typename T>
explicit Foo(T) -> Foo<T>;
那么重命名 class 时最明显的事情就是将演绎指南中的 Foo
s 更改为 Bar
s:
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>;
^
是否有任何简单和通用的方法以完全兼容的方式给出带有推导的 class 两个同时出现的名称? 我能想到的最好的方法是定义class 的 public API 两次在两个名称下,带有转换运算符,但这远非简单和通用。
你试过定义宏吗?
#define Foo Bar;
(就我个人而言,我发现它会混淆同一实现的多个名称,但我不是你。)
对不起,我现在无法测试,但我希望它有效!
你的问题正是P1814R0: Wording for Class Template Argument Deduction for Alias Templates
想要求解,也就是说,在C++20中,只需要为Bar
加上推导导数,就可以使下面的程序合式:
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中没有解决方案。