【发布时间】:2015-04-08 05:08:22
【问题描述】:
我想使用组合并使用 C++ 功能为每个可能的重载(noexcept、const、volatile)编写好的转发方法。
这个想法是使用特征来确定一个方法是否被声明为 {noexcept / const / volatile / etc.} 并做出相应的行为。
这是我想要实现的示例:
struct User{
UsedObject& obj;
User(UsedObject& obj) : obj(obj) {}
FORWARD_METHOD(obj, get); //here is where the forwarding happens
};
struct UsedObject{
string m{"Hello\n"};
string& get(double d){
cout << "\tUsed :const not called...\n";
return m;
}
const string& get(double d) const{
cout << "\tUsed :const called...\n";
return m;
}
};
这是我目前所拥有的**:
// forward with noexcept attribute
// I'm not 100% sure about : std::declval<std::add_lvalue_reference<decltype(obj)>::type
template<typename... Args>
constexpr decltype(auto) get(Args && ... args)
noexcept(
noexcept(std::declval<std::add_lvalue_reference<decltype(obj)>::type>().get( std::forward<Args>(args)... ))
and
std::is_nothrow_move_constructible<decltype( std::declval<std::add_lvalue_reference<decltype(obj)>::type>().get( std::forward<Args>(args)... ) )>::value
)
{
cout << "const called...\n";
return obj.get(std::forward<Args>(args)...);
}
// forward with noexcept and const attributes
// I'm not sure that this one behave properly.
template<typename... Args>
constexpr decltype(auto) get(Args && ... args)
const noexcept(
noexcept(std::declval< std::add_const<decltype(obj) &>::type >().get( std::forward<Args>(args)... ))
and
std::is_nothrow_move_constructible<decltype( std::declval< std::add_const<decltype(obj) &>::type >().get( std::forward<Args>(args)... ) )>::value
)
{
cout << "const not called...\n";
using const_type = std::add_lvalue_reference<std::add_const<std::remove_reference<decltype(obj)>::type>::type>::type;
return const_cast<const_type>(obj).get(std::forward<Args>(args)...);
}
请注意,这个问题与以下问题不同,因为我知道我们可以使用 c++ 特征来检查对象接口:Composition: using traits to avoid forwarding functions?
** 灵感来自@David Stone 的一系列 cmets:When should I use C++ private inheritance?。
【问题讨论】:
标签: c++ templates inheritance metaprogramming composition