Bra*_*rad 4 c++ templates c++11
我想创建一个模板,该模板在另一个返回与成员函数相同类型的对象上调用成员函数.在成员函数上使用decltype的语法有点难看,但它似乎在除了一个之外的每种情况下都有效.
这是电话:
struct container: map<string, C>
{
template< typename MemFnPtrType, typename... _ArgTypes>
auto safeOperation(string key, MemFnPtrType mfp, _ArgTypes&&... args )
-> decltype( (((C*)nullptr)->*mfp)(args...))
{
C* pC = NULL;
decltype((pC->*mfp)(args...)) result;
iterator it = find(key);
if (it != end())
{
C* pC = &(it->second);
result = (pC->*mfp)(args...);
cout << "result:" << result << "\n";
}
else
{
cout << "key: " << key << " missing\n";
}
return result;
}
};
Run Code Online (Sandbox Code Playgroud)
这可以正常工作,直到成员函数返回void.
有没有办法检测到这一点,并忽略了有问题的线?
我显然可以创建一个voidSafeOperation函数.我不介意创建另一个模板,但我想使用相同的名称"safeOperation",因此调用站点不需要根据成员函数的返回类型使用不同的帮助程序.
谢谢!
完整示例:http: //cpp.sh/7ft
不幸的是,我认为你在返回类型上不得不使用SFINAE.与类型特征开始(这是方式比你的更清洁decltype的表达)
template <typename MF, typename... Args>
using Res = typename std::result_of<MF(C, Args...)>::type;
Run Code Online (Sandbox Code Playgroud)
然后切换:
template <typename MF, typename... Args>
typename std::enable_if<
std::is_same<Res<MF, Args...>, void>::value
>::type safeOperation(string key, MF mfp, Args... args)
{
/* void case */
}
template <typename MF, typename... Args>
typename std::enable_if<
!std::is_same<Res<MF, Args...>, void>::value,
Res<MF, Args...>
>::type safeOperation(string key, MF mfp, Args... args)
{
/* non-void case */
}
Run Code Online (Sandbox Code Playgroud)
或者您可以标记发送is_void:
template <typename MF, typename... Args>
Res<MF, Args...> safeOperation(string key, MF mfp, Args... args)
{
return safeOperation(std::is_void<Res<MF, Args...>>{},
key, mfp, args...);
}
Run Code Online (Sandbox Code Playgroud)
有:
template <typename MF, typename... Args>
void safeOperation(std::true_type /* void */,
string key, MF mfp, Args... args)
{ .. }
template <typename MF, typename... Args>
Res<MF, Args...> safeOperation(std::false_type /* non-void */,
string key, MF mfp, Args... args)
{ .. }
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
639 次 |
| 最近记录: |