gpt4 book ai didi

c++ - 如何 std::forward( *this )

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

因为我想重载一个成员函数的所有cv和引用限定,我自己写了下面的宏:

#define DEFINE_FUNCTION(sig , functionality) \
sig & { functionality; } \
sig && { functionality; } \
sig const & { functionality; } \
sig const && { functionality; } \
sig volatile & { functionality; } \
sig volatile && { functionality; } \
sig const volatile & { functionality; } \
sig const volatile && { functionality; }

不幸的是,如果我想以转发方式返回 *this(即在返回类型中保留 this 指针的所有引用和 cv 限定,看来,我必须手动编写所有 8 个重载。

现在回答我的问题:是否有可能以通用方式获取 *this 的 cv 和 reference 限定类型?

我已经尝试将 decltype(auto) 作为返回类型并且

return std::forward<decltype(*this)>(*this);

但显然,结果表达式总是解析为左值引用,即使在 && 限定函数的情况下也是如此。

你能帮帮我吗?

最佳答案

你需要的是 friend 。

struct blah {
decltype(auto) foo() & { return do_foo(*this); }
decltype(auto) foo() && { return do_foo(std::move(*this)); }
decltype(auto) foo() const& { return do_foo(*this); }
decltype(auto) foo() const&& { return do_foo(std::move(*this)); }
decltype(auto) foo() const volatile& { return do_foo(*this); }
decltype(auto) foo() const volatile&& { return do_foo(std::move(*this)); }
decltype(auto) foo() volatile& { return do_foo(*this); }
decltype(auto) foo() volatile&& { return do_foo(std::move(*this)); }

blah( const volatile blah&& b ) {}
blah( const volatile blah& b ) {}
blah( const blah& b ) = default;
blah( blah&& b ) = default;
blah() = default;

template<class Self>
friend blah do_foo(Self&& self) {
std::cout << "Is reference:" << std::is_reference<Self>::value << "\n";
std::cout << "Is const:" << std::is_const<std::remove_reference_t<Self>>::value << "\n";
std::cout << "Is volatile:" << std::is_volatile<std::remove_reference_t<Self>>::value << "\n";
return decltype(self)(self);
}
};

测试代码:

blah{}.foo();
blah tmp;
tmp.foo();
const blah tmp2;
tmp2.foo();

输出:

Is reference:0
Is const:0
Is volatile:0
Is reference:1
Is const:0
Is volatile:0
Is reference:1
Is const:1
Is volatile:0

Live example.

用宏实现转发给好友的方法,手动写好友。转发给 friend 的方法甚至可以是template<class...Args>如果您可以接受完美转发的缺点。

减少在宏中运行的代码将是值得的。

#define RETURNS(...) \
noexcept(noexcept(__VA_ARGS__)) \
-> decltype( __VA_ARGS__ ) \
{ return __VA_ARGS__; }

#define FORWARD_METHOD_TO_FRIEND( NAME, SELF, REF_QUAL, HELPER_NAME ) \
template<class...Args>
auto NAME( Args&&... args ) REF_QUAL \
RETURNS( HELPER_NAME( SELF, std::forward<Args>(args)... ) )

#define FORWARD_CV_METHOD_TO_FRIEND( NAME, SELF, REF_QUAL, HELPER_NAME ) \
FORWARD_METHOD_TO_FRIEND( NAME, SELF, REF_QUAL, HELPER_NAME ) \
FORWARD_METHOD_TO_FRIEND( NAME, SELF, const REF_QUAL, HELPER_NAME ) \
FORWARD_METHOD_TO_FRIEND( NAME, SELF, const volatile REF_QUAL, HELPER_NAME ) \
FORWARD_METHOD_TO_FRIEND( NAME, SELF, volatile REF_QUAL, HELPER_NAME )

#define FORWARD_SELF_TO_FRIEND( NAME, HELPER_NAME ) \
FORWARD_CV_METHOD_TO_FRIEND( NAME, *this, &, HELPER_NAME ) \
FORWARD_CV_METHOD_TO_FRIEND( NAME, std::move(*this), &&, HELPER_NAME )

它缩短了 blah以上为:

struct blah {
FORWARD_SELF_TO_FRIEND( foo, do_foo )
// ...
template<class Self>
void do_foo( Self&& self )
{
// some_blah.foo() invokes do_foo passing it
// self with the proper qualifications
}
};

替换(和改进)所有 foo()方法。

some_blah.foo()现在调用 do_foo( some_blah )具有适当的 CV 和 L/R 值资格和 noexcept on some_blah .

constexpr可能需要一些爱才能正确,因为我们现在在 C++ 中没有条件 constexpr 测试。也许只是声称 constexpr在模板中foo generated 是正确的,但我对这个问题不太清楚。

关于c++ - 如何 std::forward( *this ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47140281/

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