gpt4 book ai didi

c++类型特征: ensuring a subclass implements a method

转载 作者:行者123 更新时间:2023-12-02 10:14:49 25 4
gpt4 key购买 nike

有一个虚拟类 C。

我想确保从 C 继承的任何具体子类都实现了一个函数“get”(如果没有,则有一个明确的编译时错误)

在这种情况下,向 C 添加虚拟“get”函数将不起作用,因为 C 子类可以实现各种签名的 get 函数。

(在我正在处理的特定情况下,pybind11 将用于创建子类的绑定(bind),并且 pybind11 对 B 的“get”方法具有强大的签名,具有广泛的签名)

在编译时检查一个类是否有函数可以通过类型特征来完成,例如

    template<class T>
using has_get =
decltype(std::declval<T&>().get(std::declval<int>()));

我的问题是我应该在代码中的哪个位置添加一个静态断言(或其他 smthg)来检查“get”函数的存在。理想情况下,这应该是 C 声明的一部分,因为从它继承的新用户代码应该很容易。也可能是完全不同的方法会更好,我想听听。

最佳答案

不确定您使用的是什么标准,但使用 C++20,您可以使用概念执行类似的操作

template<typename T>
concept HasGet = requires (T a)
{
a.get();
};

template<HasGet T>
void foo(T x)
{
x.get();
}

struct Foo
{
int get() {
return 1;
}
};

struct Bar
{
};

int main()
{
foo(Foo{});
foo(Bar{});
}

错误:
<source>: In function 'int main()':

<source>:27:12: error: use of function 'void foo(T) [with T = Bar]' with unsatisfied constraints

27 | foo(Bar{});

| ^

<source>:8:6: note: declared here

8 | void foo(T x)

| ^~~

<source>:8:6: note: constraints not satisfied

<source>: In instantiation of 'void foo(T) [with T = Bar]':

<source>:27:12: required from here

<source>:2:9: required for the satisfaction of 'HasGet<T>' [with T = Bar]

<source>:2:18: in requirements with 'T a' [with T = Bar]

<source>:4:9: note: the required expression 'a.get()' is invalid

4 | a.get();

编辑:
由于首选 C++14,如果我了解您的要求,这是您可以在 C++14 中执行的操作
#include <type_traits>
#include <utility>

using namespace std;

template<typename... Ts>
using void_t = void;

template<typename T, typename = void>
struct has_get
: false_type
{};

template<typename T>
struct has_get<T, void_t<decltype(declval<T>().get())>>
: true_type
{};

template<typename T>
static constexpr auto has_get_v = has_get<T>::value;

struct P
{

};

struct C1 : P
{
int get()
{
return 1;
}
};

struct C2 : P
{
float get()
{
return 1.0F;
}
};

struct C3
{
bool get()
{
return true;
}
};

template<typename T>
enable_if_t<is_base_of<P, decay_t<T>>::value && has_get_v<decay_t<T>>> foo(T x)
{
x.get();
}

int main()
{
foo(C1{});
foo(C2{});
foo(C3{});
}

错误:
<source>: In function 'int main()':

<source>:61:11: error: no matching function for call to 'foo(C3)'

61 | foo(C3{});

| ^

<source>:52:77: note: candidate: 'template<class T> std::enable_if_t<(std::is_base_of<P, typename std::decay<_Tp>::type>::value && has_get<typename std::decay<_Tp>::type>::value)> foo(T)'

52 | enable_if_t<is_base_of<P, decay_t<T>>::value && has_get<decay_t<T>>::value> foo(T x)

| ^~~

<source>:52:77: note: template argument deduction/substitution failed:

In file included from <source>:1:

/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/type_traits: In substitution of 'template<bool _Cond, class _Tp> using enable_if_t = typename std::enable_if::type [with bool _Cond = false; _Tp = void]':

<source>:52:77: required by substitution of 'template<class T> std::enable_if_t<(std::is_base_of<P, typename std::decay<_Tp>::type>::value && has_get<typename std::decay<_Tp>::type>::value)> foo(T) [with T = C3]'

<source>:61:11: required from here

/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/type_traits:2554:11: error: no type named 'type' in 'struct std::enable_if<false, void>'

2554 | using enable_if_t = typename enable_if<_Cond, _Tp>::type;

关于c++类型特征: ensuring a subclass implements a method,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62319516/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com