(在閱讀了這個問題及其接受的答案后,我突然想到了這個問題。)
假設一個Foo你不能修改的類,它有一個publicmember bar,但沒有 getter。
您可能想撰寫一個函式來在傳遞 a 時獲取該成員Foo,以便您可以在更高階的函式中使用它,例如std::transform和類似的函式。
換句話說,給定一個像這樣的類
struct Foo {
int bar{};
~Foo() { bar = -1; } // on most compilers this helps "verifying" that the object is dead
};
我想要一些getFoo與具有相同語意的物件,其中任何型別的物件都可以是 prvalue、xvalue 或 lvalue。getBar(expr-of-type-Foo)expr-of-type-Foo.barexpr-of-type-FooFoo
你怎么寫?
我最初想出的是:
constexpr auto getBar = overload(
[](auto& foo) -> decltype(auto) { return (foo.bar); },
[](auto const& foo) -> decltype(auto) { return (foo.bar); },
[](auto&& foo) -> auto { return foo.bar; }
);
(-> auto是多余的,但我認為在這種情況下它是有用的。)
我的推理如下。
我需要getBar它對不同的值類別有不同的表現,所以最好把它寫成一個多載集;為此,我正在使用boost::hana::overload.
但是我不確定我發現它的解決方案是最小的(假設它足夠了)。
例如,
給定我在
auto&/auto const&/上多載的多載之一auto&&,后者只會捕獲右值,所以在其他兩種情況下,我知道我想回傳一個參考,所以我可以回傳-> auto&and-> auto const&而不是decltype(auto)甚至洗掉括號returned 運算式:constexpr auto getBar = overload( [](auto& foo) -> auto& { return foo.bar; }, [](auto const& foo) -> auto const& { return foo.bar; }, [](auto&& foo) -> auto { return foo.bar; } );不過,在這一點上,我認為我不需要兩個多載
(auto&) -> auto&/(auto const&) -> auto const&,因為前者在輸入const運算式時自然會決議為后者,所以我想我可以這樣做:constexpr auto getBar = overload( [](auto& foo) -> auto& { return foo.bar; }, [](auto&& foo) -> auto { return foo.bar; } );
但目前我沒有看到進一步簡化它的方法。
這是我的測驗嘗試:
#include<assert.h>
#include<boost/hana/functional/overload.hpp>
struct Foo {
int bar{};
~Foo() {
bar = -1;
}
};
int main() {
{
constexpr auto getBar = overload(
[](auto&& foo) -> auto { return foo.bar; },
[](auto& foo) -> auto& { return foo.bar; }
);
{
Foo foo{3};
assert(&getBar(foo) == &foo.bar);
assert(getBar(foo) == 3);
foo.bar = 4;
assert(foo.bar == 4);
assert(getBar(foo) == 4);
getBar(foo) = 5;
assert(foo.bar == 5);
assert(getBar(foo) == 5);
}
{
Foo const foo{3};
assert(&getBar(foo) == &foo.bar);
assert(getBar(foo) == 3);
//foo.bar = 3; // Expectedly fails to compile.
//getBar(foo) = 3; // Expectedly fails to compile.
}
{
auto const& foobar = getBar(Foo{3});
assert(foobar == 3);
//foobar = 5; // Expectedly fails to compile.
}
{
//auto& foobar = getBar(Foo{3}); // Expectedly fails to compile.
//auto& foobar = Foo{3}.bar; // Expectedly fails to compile.
}
}
}
uj5u.com熱心網友回復:
好吧,對于最少的作業:
const auto getBar = std::mem_fn(&Foo::bar);
這個特定的用例似乎可以滿足您的需求。在 C 20 中,它被升級為constexpr,但它可能可用也可能不可用。與另一個具有可多載成員函式的問題不同,成員變數不是模棱兩可的。所以我會回到上面。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/533014.html
