C++20 Concepts 语言功能允许限制模板类的成员函数。 但是,这些约束仅适用于成员函数的主体,而不适用于声明 - 声明仍然需要有效。
我面临的情况是声明在语义上可能无效,但只要用户不尝试调用该成员函数,我就想避免编译错误。
例如:
#include <vector>
template <typename T>
struct A {
// how to rewrite this declaration so that it works?
typename T::value_type f(typename T::value_type x) requires std::integral<typename T::value_type> {
return x * 10;
}
};
int main(){
A<std::vector<int>> a; // compiles
A<int> b; // does not compile, but we want this to compile as long as the user doesn't call `b.f`
struct B { using value_type = void; };
A<B> c; // does not compile, but we want this to compile as long as the user doesn't call `c.f`
}
编译错误为:
<source>: In instantiation of 'struct A<int>':
<source>:12:12: required from here
12 | A<int> b; // does not compile
| ^
<source>:5:28: error: 'int' is not a class, struct, or union type
5 | typename T::value_type f(typename T::value_type x) requires std::integral<typename T::value_type> {
| ^
<source>: In instantiation of 'struct A<main()::B>':
<source>:14:10: required from here
14 | A<B> c; // does not compile
| ^
<source>:5:28: error: invalid parameter type 'main()::B::value_type' {aka 'void'}
5 | typename T::value_type f(typename T::value_type x) requires std::integral<typename T::value_type> {
| ^
<source>:5:28: error: in declaration 'typename T::value_type A<T>::f(typename T::value_type) requires integral<typename T::value_type>'
重写成员函数的声明
f
以便代码可以编译的惯用方法是什么?
我不确定是否惯用,但你可以使用一个技巧——有一个相同的模板参数,直到稍后才被替换:
template<typename U = T>
requires std::integral<typename T::value_type>
typename U::value_type f(typename U::value_type x) {
return x * 10;
}
期望永远不会显式提供此模板参数。它意味着始终使
U
与 T
具有相同的类型,但由于它 可能 可以更改它,因此在 T
时不会发生替换,因此避免了硬错误。