gpt4 book ai didi

c++ - 编译时检查输出(<<)和关系(<、> 等)是否可用

转载 作者:太空狗 更新时间:2023-10-29 23:05:59 25 4
gpt4 key购买 nike

我目前正在使用 is_call_possible 第 3 方代码

https://github.com/jaredhoberock/is_call_possible

在编译时确定成员是否可用。这个例子效果很好:

#include <string>
#include "is_call_possible.h"

DEFINE_IS_CALL_POSSIBLE(is_call_possible, operator())
DEFINE_IS_CALL_POSSIBLE(test_available, test)

struct Foo {
void operator()(double) {}
double test(std::string) { return 0; }
};

int main(int argc, const char * argv[]) {
static_assert(is_call_possible<Foo, void(double)>::value,"err"); //success
static_assert(test_available<Foo, double(std::string)>::value,"err"); //success
return 0;
}

但这对普通非成员不起作用,所以我不能对输出和关系运算符做同样的事情:

DEFINE_IS_CALL_POSSIBLE(output_available, operator<<) //error
DEFINE_IS_CALL_POSSIBLE(less_available, operator<) //error
DEFINE_IS_CALL_POSSIBLE(greater_available, operator>) //error

你能给我指出方便的第 3 方代码(或你自己的代码)来适应这个吗?

底层解决方案(“第 3 方代码”)可以在 C++11 中实现,如果它更容易的话,但我想我不会注意到我自己的代码中的差异(作为第 3 方代码的用户) .

最佳答案

假设 C++11 是一个选项,decltype编译时构造可以与 SFINAE 结合使用,基本上对类型进行“概念检查”(尽管 C++11 标准中缺少真正的概念检查),以查看它们是否支持操作。

(未经测试,因为我目前缺少 C++11 编译器 [诅咒你的 Windows~!],但我相信如果存在错误,有人会发现我的错误)。

例如

template<typename T> struct voidify{typedef void type;};
template<typename T, typename U, typename enable=void>
struct has_operator_less {
enum{value=false};
};
template<typename T, typename U>
struct has_operator_less<T, U, typename voidify<decltype(
std::declval<T>() < std::declval<U>() // <-- this is the 'concept' check
)>::type> {
enum{value=true};
};

然后您使用它来启用/禁用 std::enable_if构建依赖于 operator< 存在与否的任何函数存在这两种类型:

template<typename T, typename U>
typename std::enable_if<
has_operator_less<T, U>::value, I_am_the_result_type_of_the_function
>::type
I_depend_on_the_existence_of_the_less_than_operator(const T& a, const U& b) {...}

如果您想要为缺少 operator< 的类型实现该函数的替代实现,你只需启用否定:

template<typename T, typename U>
typename std::enable_if<
!has_operator_less<T, U>::value, I_am_the_result_type_of_the_function
// ^ note the negation
>::type
I_depend_on_the_existence_of_the_less_than_operator(const T& a, const U& b) {...}

因此,现在您可以在编译时确定具有和不具有这些运算符的类型的实现,并且可以对任何其他运算符或函数名称或任何重复此解决方案你要。只需将您正在检查的概念放在 decltype 中即可。 .

而且这些都不需要在构建之前有一个单独的配置步骤。

(同样,未经测试的代码 -.-' 但肯定是正确的;其他人都知道编辑按钮在哪里 :-P )

关于c++ - 编译时检查输出(<<)和关系(<、> 等)是否可用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17243414/

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