使用`auto`作为函数参数是否违反了C++标准?

3

像这样的代码:

auto add(auto a, auto b) { return a + b; }

违反了ISO C++14标准吗?未来的标准版本是否允许编写这样的代码?


2
这是概念 TS 的一部分,而不是 C++14。出于某种原因,我找不到重复项... - Barry
是的,我已经修复了。 - Alecto Irene Perez
逻辑告诉我们编译器无法推断类型,因此这是行不通的。(而且由于函数没有模板化,所以没有理由根据需求创建重载。) - user1196549
3
@YvesDaoust 这没有意义。 - Barry
4个回答

7

这是否违反了ISO c++14标准?

是的,在C++14(或C++17)中,您不能使用auto声明带参数的函数。此代码是不合法的。

未来版本的标准是否允许编写这样的代码?

当前的概念TS确实允许这样做,通常称为简洁的函数模板语法。在概念中,其含义等同于:

template <class T, class U>
auto add(T a, U b) { return a + b; }

概念提议中的那部分还允许使用概念名称,而不仅限于auto。现在尚不确定这是否会成为未来C++标准的一部分。


更新:该代码将在C++20中有效,并且具有与我上面展示的函数模板等效的含义(注意:ab是独立推断的)。


3
如果你想意味着可以将任何类型传递给函数,那么将其作为模板即可:
template <typename T1, typename T2> int add(T1 a, T2 b);

或者,您可以使用lambda:

auto add = [](const auto& a, auto& b){ return a + b; };

这是泛型(多态)lambda表达式的提案。但是,泛型lambda是C++14的功能。


OP在谈论函数,而不是lambda表达式... -1。 - Barry
2
Lambda 可以被视为函数声明的定义,Lambda 是一种函数但是是间接地实现的。 - Soner from The Ottoman Empire
在你的第一个例子中,ab必须具有相同的类型,并且在任何意义上都不等同于你的lambda或OP似乎要求的内容。 - Ryan Haining
@snr 我确定是在我写那篇文章的时候。 - Ryan Haining
你的函数为什么返回一个 int?那绝对不等同于 OP 的代码。 - Praetorian

1

目前这是无效的,但也许在未来版本的标准中,它将相当于:

template<typename T1, typename T2>
auto add(T1 a, T2 b) {return a + b;}

-1
对于C++ 20及以上版本,这是有效的,并且会按照你的预期进行操作。
对于不支持C++ 20的编译器,可以使用函数宏和模板来解决这个问题。
#define add(a,b) add_real_function<decltype(a),decltype(b)>(a,b)

template <typename T1,typename T2>
auto add_real_function(T1 a, T2 b) { return a + b; }

请记住,您的函数的真实名称(这里是add_real_function)必须与您想要为函数指定的名称(这里是add)不同,后者必须是宏的名称。
不幸的是,这种解决方法的缺点是您无法创建指向这种类型函数的函数指针。

OP 的代码在 C++20 中是有效的。你的代码过于复杂,你可以将参数中的 auto 替换为 T1T2,然后可以移除宏定义。此外,你的版本也需要 C++20,因为它使用了与 OP 代码相同的特性。 - HolyBlackCat
关于编辑:现在,宏完全是不必要的,因为编译器可以推断出add_real_function的模板参数。 - HolyBlackCat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接