假设我有一个将两个值相加的函数.如果我对类型一无所知,那么我基本上必须写两次函数; 一次在实际返回值中,再次作为返回类型说明符:
template <typename A, typename B>
auto Add(const A& a, const B& b) ->std::decay<decltype(a + b)>::type
{
return a + b;
}
Run Code Online (Sandbox Code Playgroud)
虽然这有效,但它是不可取的,因为它难以阅读且难以维护.
在C++ 14中,这不会是一个问题,因为我们可以删除返回类型说明符(我不确定它会不会衰减...).现在,我坚持使用C++ 11.
根据我的经验,无论何时我在C++中寻找尚未进入标准的功能,但有明显的需求,Boost库通常都有一个解决方案.我搜索了文档,但是我找不到任何可能对我有帮助的东西.这些BOOST_AUTO_RETURN和BOOST_TYPEOF_TPL功能似乎更多旨在为C++ 03用户提供C++ 11功能.
基本上我所追求的是执行以下功能的东西:
template <typename A, typename B>
auto Add(const A& a, const B& b)
{
return a + b; // Deduce return type from this, like C++14 would
}
Run Code Online (Sandbox Code Playgroud)
Boost库中是否有一些我不知道的功能(或C++ 11中的一个漂亮的技巧)可能允许我-> decltype(...)在每次自动返回类型后放弃显式?这将如何实施?
小智 26
C++ 11中唯一可能的推导函数返回类型是lambda的返回类型.但是,C++ 11限制了lambdas的使用.这有效:
auto add = [](int a, int b) { return a + b; };
Run Code Online (Sandbox Code Playgroud)
这是有效的,并定义add为定义operator()返回的成员函数的lambda int.由于lambda没有捕获任何东西,你甚至可以写
auto add = +[](int a, int b) { return a + b; };
Run Code Online (Sandbox Code Playgroud)
制作add一个常规的函数指针:它获取类型int(*)(int, int).
但是,C++ 11不允许将参数类型指定为auto,也不允许将add其定义为模板变量,因此您不能使用它来泛化推断返回类型.尝试将其包装在模板类中失败:
template <typename A, typename B>
struct S { static auto add = [](A a, B b) { return a + b; }; }; // invalid
Run Code Online (Sandbox Code Playgroud)
add在这里初始化类是无效的,auto除非成员在课堂上初始化,否则你不能使用它.此外,即使它确实有效,它也不会允许扣除A或者B,这似乎更像是你所追求的.
鉴于这些限制,我没有看到任何替代方案,只能重复表达.不过,你可以在一个简单的宏中隐藏重复.
#define AUTO_RETURN(func, ...) auto func -> decltype(__VA_ARGS__) { return __VA_ARGS__; }
template <typename A, typename B>
AUTO_RETURN(add(A a, B b), a + b)
Run Code Online (Sandbox Code Playgroud)
或者Marc Glisse指出的变种,
#define RETURNS(...) noexcept(noexcept(__VA_ARGS__)) -> decltype(__VA_ARGS__) { return __VA_ARGS__; }
template <typename A, typename B>
auto add(A a, B b) RETURNS(a + b)
Run Code Online (Sandbox Code Playgroud)
看起来有点干净.
我不知道Boost中可能有类似的东西.无论如何,考虑到琐事,Boost在这里似乎有些过分.
| 归档时间: |
|
| 查看次数: |
2015 次 |
| 最近记录: |