gpt4 book ai didi

c++ - 尾随返回类型、declval 和引用限定符 : can they work together?

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:08:01 25 4
gpt4 key购买 nike

考虑以下示例:

#include <utility>

struct A { void f() {} };
struct B { void f() & {} };
struct C { void f() && {} };

template<typename T>
auto f() -> decltype(std::declval<T>().f())
{}

int main() {
f<A>();
// f<B>(); // (*)
f<C>();
}

当用 B 调用时(第 (*) 行),代码不再编译 std::declval 转换 T 在特定情况下为右值引用类型。
如果我们稍微改变一下,就会遇到相反的问题:

// ...

template<typename T>
auto f() -> decltype(std::declval<T&>().f())
{}

// ...

int main() {
f<A>();
f<B>();
// f<C>(); // (*)
}

(*) 处的行不适用于 std::declval,在特定情况下将类型转换为左值引用类型。

有没有什么方法可以定义一个接受类型 T 的表达式,如果它有一个成员函数 f,而不管它的引用限定符是什么?


<子>我没有任何真实的案例可以使用它,我也无法举出任何真实的使用示例。
这个问题是为了好奇,仅此而已。
我知道如果有 ref-qualifier 是有原因的,我不应该试图破坏类的设计。

最佳答案

构建一个类型特征,如果表达式 declval<T>().f(declval<Args>()...) 则返回 true是一个有效的电话。然后传入U&U&&表示 T 类型的左值或右值对象.

namespace detail{
template<class...>struct voider{using type=void;};
template<class... Ts>using void_t=typename voider<Ts...>::type;

template<template<class...> class, class=void, class...>
struct can_apply : false_type { };

template<template<class...> class L, class... Args>
struct can_apply<L, void_t<L<Args...>>, Args...> : true_type {};

template<class T>
using rvalue = decltype(declval<T>().f());
template<class T>
using lvalue = decltype(declval<T&>().f());

template<class T>
using can_apply_f
= integral_constant<bool, detail::can_apply<rvalue, void_t<>, T>{} ||
detail::can_apply<lvalue, void_t<>, T>{}>;
}

template<class T>
enable_if_t<detail::can_apply_f<T>{}>
f();

在 C++17 中,这变得更简单了:

namespace detail{
auto apply=[](auto&&g,auto&&...xs)->decltype(decltype(g)(g).f(decltype(xs)(xs)...),void()){};

template<class T>
using ApplyF = decltype(apply)(T);

template<class T>
using can_apply_f = std::disjunction<std::is_callable<ApplyF<T&>>, std::is_callable<ApplyF<T&&>>>;
}

关于c++ - 尾随返回类型、declval 和引用限定符 : can they work together?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40454893/

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