C++ 如何使用Boost实现C++;14款自动退货类型?

C++ 如何使用Boost实现C++;14款自动退货类型?,c++,c++11,boost,C++,C++11,Boost,假设我有一个将两个值相加的函数。如果我对类型一无所知,那么我基本上必须编写两次函数;一次输入实际返回值,另一次作为返回类型说明符: template <typename A, typename B> auto Add(const A& a, const B& b) ->std::decay<decltype(a + b)>::type { return a + b; } Boost库中是否有一些我不知道的功能(或C++11中的一个巧妙技巧),允

假设我有一个将两个值相加的函数。如果我对类型一无所知,那么我基本上必须编写两次函数;一次输入实际返回值,另一次作为返回类型说明符:

template <typename A, typename B>
auto Add(const A& a, const B& b) ->std::decay<decltype(a + b)>::type
{
  return a + b;
}

Boost库中是否有一些我不知道的功能(或C++11中的一个巧妙技巧),允许我在每次自动返回类型之后放弃显式的
->decltype(…)
?这将如何实现?

在C++11中,唯一可能的推断函数返回类型是lambda的返回类型。不过,C++11限制了lambdas的使用。这项工作:

auto add = [](int a, int b) { return a + b; };
这是有效的,并将
add
定义为lambda,该lambda定义了返回
int
运算符()
成员函数。因为lambda不能捕获任何东西,所以您甚至可以编写

auto add = +[](int a, int b) { return a + b; };
要使
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
或者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)
#define RETURNS(…)noexcept(noexcept(uu VA_ARGS_uu))->decltype(u VA_ARGS_uu){return u VA_ARGS_u;}
模板
自动添加(A、B)返回(A+B)
看起来干净一点


Boost中可能已经有类似的东西了,我不知道。不管怎样,考虑到这些琐碎的东西,Boost在这里似乎有些过火。

有一个库试图模拟这种语法。然而,它只对叮当声有效。由于这些错误和错误,它在gcc上不起作用。对于gcc 4.9,它们可能是固定的,但如果您使用gcc 4.9,无论如何,您可以使用自动返回类型。

那些将其标记为非主题的人应该真正审查指导原则:这是一个关于特定的、可重复的问题,有足够的信息进行诊断。这不是家庭作业,也不是征求建议。@CareyGregory就像我说的,我认为你应该回顾一下指导方针。询问是否可以做某件事并不会使它偏离主题。@Puppy:仅仅因为文档中存在某件事,并不意味着它显然与问题有关或易于使用,特别是对于没有经验的人。如果这是真的,那么就应该关闭,因为所有的东西都被记录在某处…@Puppy这个网站上没有任何问题不能通过告诉某人“去读点东西”来回答,但这并不意味着这样的回答有帮助或有成效,也不意味着原来的问题在某种程度上是无效的。我仍然不明白这为什么会引起如此大的争议。在“在y的情况下我如何做x?”和“请让我参考非现场资源”之间存在着差异。这种差异应该是非常明显的。前者完全符合这里的主题,后者则不然。请注意,许多表面上属于后一类的问题可以重新表述为属于前一类。这里有一个教训:如果你想知道如何去做某件事,问一下如何去做,而不是间接地找一个能告诉你如何去做的向导。如果回答者愿意并认为合适,他们可以在回答中自由链接到这些资源。宏是通常的解决方案(您也可以为正文的第三次使用添加noexcept),尽管通常func被保留在宏之外,因此看起来像是
add(a,B)返回(a+B)
@marglisse完成,它看起来像是
auto add(A,B)返回(A+B)
,我希望
auto
成为宏扩展结果的一部分。不过,现在看看你的表单,我确实觉得它看起来好多了,所以我把它编辑进去了。谢谢@bamboon Boost很有用,但除非在最新版本中进行了更改,否则它存在版本控制问题,即将多个项目链接在一起,所有项目都使用Boost,并且不使用同一版本,会导致大问题,Boost向后兼容不足,无法相信使用相同版本编译所有项目不会破坏任何项目。因此,如果我没有充分的理由使用Boost,我会犹豫是否使用Boost。请注意,这是对C++14
decltype(auto)
的模拟,而不是像OP所要求的那样简单的
auto
,但是在使用
decay
的情况下制作两个版本的宏是很简单的。此外,与C++14语法相比,这种模拟实际上有一些优点,因为它允许使用SFINAE。我经常将
->
返回中删除,以便
自动添加(A,B)->返回(A+B)
,我觉得这很不错。但是它确实花费了
noexcept
。在4.8中,链接的两个bug都被标记为已修复,这是错误的吗?GCC4.8.3的错误是,它不是您链接到的两个bug之一。我在clang 3.4.2中遇到的错误是“lambda表达式可能不会出现在常量表达式中”,这似乎相当明确,因为这不会起作用,至少在clang的版本中不会。顺便说一下,我在这里包含了一些注释,表明代码是无效的,但我的推理是错误的,所以我删除了它们。我不知道像你这样的回答是否有效。无论如何,这是一个巧妙的把戏。
#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)
#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)