gpt4 book ai didi

c++ - 根据函数签名将引用作为左值/右值传递

转载 作者:行者123 更新时间:2023-11-28 06:20:26 28 4
gpt4 key购买 nike

假设我有一些数据:

struct Bar {};

我需要包装一个函数并将这些数据提供给它。

template<typename F>
void foo(F f) {
Bar bar;
f(bar);
}

正如您在这个简单示例中所见:

  • bar 不是临时的
  • 调用f后我不需要它

我要支持多个函数签名,比如:

foo([](Bar){}); // (1)
foo([](Bar&){}); // (2)
foo([](Bar&&){}); // (3)

但是 gcc 提示:

f(bar); // (3) : cannot bind 'Bar' lvalue to 'Bar&&'
f(std::move(bar)); // (2) : no match for call to ...

你会怎么做才能同时获得两者?

最佳答案

struct BarIsh{
Bar&b;
operator Bar&&()&&{return std::move(b);}
operator Bar&()&&{return b;}
};

然后 f(BarIsh{bar})

缺点是,如果 f 采用推导参数,它得到的是 BarIsh 而不是 Bar

假设您有一个 SFINAE 友好的 result_of...

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

template<class...>struct types{using type=types;};

namespace details{
template<template<class...>class Z,class types,class=void>
struct can_apply:std::false_type{};
template<template<class...>class Z,class...Ts>
struct can_apply<Z,types<Ts...>,void_t<Z<Ts...>>>:
std::true_type
{};
};
template<template<class...>class Z,class...Ts>
using can_apply=details::can_apply<Z,types<Ts...>>;

template<class Sig>
using result_of_t=typename std::result_of<Sig>::type;

template<class Sig>
using can_invoke=can_apply<result_of_t,Sig>;

现在我们可以测试了。

template<typename F>
void foo(F&& f,std::true_type)
{
Bar bar;
std::forward<F>(f)(std::move(bar));
}

template<typename F>
void foo(F&& f,std::false_type)
{
Bar bar;
std::forward<F>(f)(bar);
}


template<typename F>
void foo(F f)
{
foo(std::forward<F>(f),can_apply<F(Bar&&)>{});
}

完成了。 (上面可能有错别字,手机写的代码)

关于c++ - 根据函数签名将引用作为左值/右值传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29389030/

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