让模板类的成员函数具有仅当模板参数满足某些概念时才有效的声明的惯用方法是什么?

问题描述 投票:0回答:1

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
以便代码可以编译的惯用方法是什么?

c++ c++20 c++-concepts c++23 requires-clause
1个回答
0
投票

我不确定是否惯用,但你可以使用一个技巧——有一个相同的模板参数,直到稍后才被替换:

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
时不会发生替换,因此避免了硬错误。

© www.soinside.com 2019 - 2024. All rights reserved.