在 C++11 中,是否可以执行类似于以下的操作?
template<typename T, size_t N>
void foo(array<T, N> src) { ... }
...
foo({1, 2, 3})
我目前正在运行 GCC 4.8。
在 C++11 中,是否可以执行类似于以下的操作?
template<typename T, size_t N>
void foo(array<T, N> src) { ... }
...
foo({1, 2, 3})
我目前正在运行 GCC 4.8。
是的,我设法完成了以下工作(因为您允许类似的事情):
template<typename T, size_t N>
void foo(array<T, N> src) { ... }
...
foo('a', 'b');
foo(1, 2, 3);
方法如下:
#include <array>
#include <iostream>
#include <utility>
using namespace std;
template<typename T, unsigned long N>
void foo(array<T,N> src) {
for (auto e : src)
cout << e << endl;
}
template<class T, class... Tail>
auto make_array(T head, Tail... tail) -> std::array<T, 1 + sizeof...(Tail)>
{
std::array<T, 1 + sizeof...(Tail)> a = {{ head, tail ... }};
return a;
}
template<class T, class... Tail>
void foo(T&& head, Tail&&... values) {
foo(make_array(std::forward<T>(head), std::forward<Tail>(values)...));
}
int main() {
foo('a', 'b');
foo(1, 2, 3);
}
我已经用 gcc 4.7.2 和 clang 3.4 (trunk 184647) 对此进行了测试,它们按预期工作。
这是 Stacked-Crooked 的在线版本。但是,此代码无法在 Ideone 编译。由于我无法弄清楚传递给 Ideone 编译器的选项,因此我放弃了该站点。
我make_array
从@Pavel Minaev对如何使用 std::array 模拟 C 数组初始化“int arr[] = { e1, e2, e3, ... }” 行为的回答中无耻地窃取了函数?问题。其他make_array
建议导致我无法修复的编译错误。
此make_array
功能有局限性,请阅读全文;特别是讨论std::array - 如果它知道它在 comp.lang.c++.moderated 上的大小被引用。显然,得到一个合理make_array
的是相当棘手的。我不建议make_array
将此答案中的头脑简单的人用于生产代码。
如果 size 是std::initializer_list
. 因此问题为什么大小不是 std::initializer_list 的模板参数?
显然不是。标准 (14.8.2.5) 将此称为非推断上下文;
然而,在某些情况下,该值不参与类型推导,而是使用在其他地方推导或明确指定的模板参数的值。
...
未推断的上下文是:
...
- 一个函数形参,其关联实参是一个初始化列表 (8.5.4) 但该形参没有 std::initializer_list 或对可能有 cv 限定的 std::initializer_list 类型的引用。
例子:
模板<class T> void g(T);
g({1,2,3}); // 错误:没有为 T 推导出参数
编辑:如果您只是使用重载来使类型的扣除起作用,您可以使用相同的东西;std::vector
initializer_list
template<typename T>
void foo(const std::vector<T>& src) { ...your code here... }
template<typename T>
void foo(const std::initializer_list<T>& src) { foo(std::vector<T>(src)); }
foo({1,2,3}); // Compiles
...但遗憾的是,由于 的大小initializer_list
不是模板参数,我想不出一种方法让它以与类型相同的方式推断和转发数组大小。initializer_list
您可以直接使用初始化列表来实现该语法。例如:
#include <iostream>
#include <initializer_list>
void foo(std::initializer_list<int> il) {
for (auto i: il)
std::cout << i < std::endl;
}
int main() {
foo({1,2,3});
}
或使其更通用:
template <typename T>
void foo(std::initializer_list<T> il) {
...
对原始数组的引用是可能的:
template <typename T, size_t N>
void foo(T const (&x)[N]) {
// x is [1, 2, 3], N = 3
}
int main() {
foo({1, 2, 3});
return 0;
}
请注意,必须声明数组const
。