要真正着一個成員函數的調用,一個必須考慮的正確轉發爲成員呼叫*this
值的必要性。
以下:
template<typename Type>
struct Fwd {
Type member;
template<typename ...Args>
decltype(auto) Func(Args&&... args)
noexcept(noexcept(member.Func(std::forward<Args>(args)...)))
{ return member.Func(std::forward<Args>(args)...); }
};
是足夠的轉發參數和異常規範,因爲你可能已經猜到了。但它不足以完全向前*this
:
struct S {
// These overloads are reachable through Fwd<S>::Func().
void Func(int) & {}
void Func(int&&) & {}
// These other overloads are not.
void Func(int) const&;
void Func(int&&) const&;
void Func(int) volatile&;
void Func(int&&) volatile&;
void Func(int) const volatile&;
void Func(int&&) const volatile&;
void Func(int) &&;
void Func(int&&) &&;
// (These are rather uncommon, just provided for completude.)
void Func(int) const&&;
void Func(int&&) const&&;
void Func(int) volatile&&;
void Func(int&&) volatile&&;
void Func(int) const volatile&&;
void Func(int&&) const volatile&&;
};
有此問題的兩個解決方案。一種方法是簡單地手動創建的每一個其他可能的過載,這可能與宏:
#define FWD(member, Func) \
template<typename ...Args> \
decltype(auto) Func(Args&&... args) & \
noexcept(noexcept(member.Func(std::forward<Args>(args)...))) \
{ return member.Func(std::forward<Args>(args)...); } \
\
template<typename ...Args> \
decltype(auto) Func(Args&&... args) const& \
noexcept(noexcept(member.Func(std::forward<Args>(args)...))) \
{ return member.Func(std::forward<Args>(args)...); } \
\
template<typename ...Args> \
decltype(auto) Func(Args&&... args) volatile& \
noexcept(noexcept(member.Func(std::forward<Args>(args)...))) \
{ return member.Func(std::forward<Args>(args)...); } \
\
template<typename ...Args> \
decltype(auto) Func(Args&&... args) const volatile& \
noexcept(noexcept(member.Func(std::forward<Args>(args)...))) \
{ return member.Func(std::forward<Args>(args)...); } \
\
template<typename ...Args> \
decltype(auto) Func(Args&&... args) && \
noexcept(noexcept(member.Func(std::forward<Args>(args)...))) \
{ return std::move(member).Func(std::forward<Args>(args)...); } \
\
template<typename ...Args> \
decltype(auto) Func(Args&&... args) const&& \
noexcept(noexcept(member.Func(std::forward<Args>(args)...))) \
{ return std::move(member).Func(std::forward<Args>(args)...); } \
\
template<typename ...Args> \
decltype(auto) Func(Args&&... args) volatile&& \
noexcept(noexcept(member.Func(std::forward<Args>(args)...))) \
{ return std::move(member).Func(std::forward<Args>(args)...); } \
\
template<typename ...Args> \
decltype(auto) Func(Args&&... args) const volatile&& \
noexcept(noexcept(member.Func(std::forward<Args>(args)...))) \
{ return std::move(member).Func(std::forward<Args>(args)...); }
template<typename Type>
struct Fwd {
Type member;
FWD(member, Func)
};
另一解決方案是完全避免一個成員函數和使用一個免費的功能:
template<typename Fwd, typename ...Args>
decltype(auto) Func(Fwd&& fwd, Args&&... args)
noexcept(noexcept(std::forward<Fwd>(fwd).Func(std::forward<Args>(args)...))) {
return std::forward<Fwd>(fwd).Func(std::forward<Args>(args)...);
}
你指的是你的'insert'包裝的返回類型? 'decltype(auto)' – dyp
參數列表後的'something'應該包含正確的cv-和ref-qualifiers和exception-specification? – dyp
「將_data的給定函數傳遞給MyClass的正確語法是什麼」 - > Erm,什麼? – fredoverflow