有没有一种方法在C++中将auto作为参数传递?

71

有没有办法将auto作为参数传递给另一个函数?

int function(auto data)
{
    //DOES something
}

4
取决于您希望它能够做什么。您需要哪些功能模板无法提供? - Quentin
1
这是一个可怕的想法。参数类型不仅是为了让你知道函数需要哪些类型,也是为了让其他人知道。只需要花3秒钟写出类型,不要那么懒(或者如果类型不固定,可以使用模板)。 - Synxis
是的,使用C++1z概念,你可以做到这一点 :) - Navin
@Synxis 这并不总是一个可怕的想法。如果类型足够复杂,用 auto 替换它可能更易读(假设有一个有意义的变量名)。此外,我认为 void f(auto t);template<typename T> void f(T t); 更易读,假设 f 内部没有明确要求使用 T - pasbi
假设有一个有意义的变量名。这听起来像字符串类型,并希望得到最好的结果(实际上,您总是会被欺骗)。我也更喜欢较长的形式,因为它更明确模板的作用;也许有一天我会改变,但只有在掌握概念之后! - Synxis
4个回答

81

C++20允许将auto作为函数参数类型

以下代码在C++20中是有效的:

int function(auto data) {
   // do something, there is no constraint on data
}

作为缩写函数模板
这是非约束类型约束的特例(即未约束的自动参数)。 使用概念,限制类型约束版本(即受限自动参数)的示例为:
void function(const Sortable auto& data) {
    // do something that requires data to be Sortable
    // assuming there is a concept named Sortable
}

这里是规范中的措辞,借助我的朋友Yehezkel Bernat

9.2.8.5 占位符类型说明符 [dcl.spec.auto]

placeholder-type-specifier:

type-constraintopt auto

type-constraintopt decltype ( auto )

  1. 占位符类型说明符指定了一个占位符类型,该类型将在初始化程序中通过推导后被替换。

  2. 形如 type-constraintopt auto 的占位符类型说明符可以用于函数声明或 lambda 表达式的参数声明的 decl-specifier-seq 中,表示该函数是一个缩写的函数模板(9.3.3.5)...


在gcc中,如果您提供了-fconcepts选项,也可以使用旧版本的标准(-std=c++14-std=c++17)来实现相同的效果。 - s.yadegari

72
如果你希望函数能够接收任意类型的参数,可以将其定义为模板形式:
template <typename T> int function(T data);

有一个建议允许使用你所用的语法(就像C++14已经为通用lambda函数所做的那样),但它目前还不是标准。

C++ 2020现在支持自动函数参数。请参见Amir的答案


1
我在想:这是不是同一件事呢?也就是说,对于每个 T 都会有一个 function<T>,而对于 auto 只有一个,因为它的推导是会改变的。或者我错了吗? - edmz
5
这句话的意思是:“这只是一种更短的编写方式,对于每个被推导为auto的参数类型,将实例化一个不同的函数,就像对于命名的模板参数一样。” - Mike Seymour
1
我原以为隐式模板参数应该受到概念的限制...现在概念完全死了吗?还是auto用于无限制的参数,而(某天)概念用于有限制的参数? - Ben Voigt
1
@BenVoigt:我不知道,我的超自然能力不足以知道C++17最终会变成什么样子。概念肯定没有死亡,并且可能会出现在该标准中;但是是否允许无约束的“auto”函数参数与它们有些无关。 - Mike Seymour
2
@BenVoigt 是的,这就是想法。Concepts Lite 引入了 auto 作为无约束参数的简写,并引入了概念来限制参数。 - Rapptz
今天是2019年,标准大部分已经准备就绪,auto被允许作为函数参数声明。这被称为“缩写函数模板”:https://en.cppreference.com/w/cpp/language/function_template#Abbreviated_function_template - xtofl

32

模板是您使用普通函数完成此操作的方式:

template <typename T>
int function(T data)
{
    //DOES something
}

另外,您可以使用lambda:

auto function = [] (auto data) { /*DOES something*/ };

5
通用 lambda 是 C++14 的一项特性。 - TartanLlama

-1

我不知道什么时候改变了,但目前使用C++14可以实现问题中的语法:

https://coliru.stacked-crooked.com/a/93ab03e88f745b6c

这只是一个警告:

g++ -std=c++14 -Wall -pedantic -pthread main.cpp && ./a.out main.cpp:5:15: 警告:在参数声明中使用'auto'仅在-fconcepts可用 void function(auto data)

使用c++11会出现错误:

main.cpp:5:15: 错误:在参数声明中使用'auto'仅在-std=c++14或-std=gnu++14可用


1
正如您所见,这是gcc特定的扩展,旨在仅与Concepts TS一起使用。随着C++20中的概念成为标准,这将成为一项标准功能。 - Yehezkel B.

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