在C ++ 11中,是否可以执行类似以下的操作?
template<typename T, size_t N>
void foo(array<T, N> src) { ... }
...
foo({1, 2, 3})
我目前正在运行GCC 4.8。
答案 0 :(得分:6)
是,我设法完成了以下工作(因为您允许类似的东西):
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)进行了测试,它们按预期工作。
这是一个在线版本at Stacked-Crooked.但是,此代码无法在Ideone上编译。由于我无法弄清楚在Ideone上传递给编译器的选项,我已经放弃了该网站。
我从@Pavel Minaev对How to emulate C array initialization “int arr[] = { e1, e2, e3, … }” behaviour with std::array?问题的回答中无耻地窃取make_array
函数。其他make_array
建议导致编译错误,我无法解决。
此make_array
功能有局限性,请阅读the entire post;特别是关于comp.lang.c ++。moderated的讨论std::array - if only it knew its size被引用。显然,获得合理的make_array
非常棘手。 我不建议在此答案中使用简单明了的make_array
来在生产代码中使用。
如果大小是std::initializer_list
的模板参数,则不会有任何问题。因此问题为Why is the size not a template argument of std::initializer_list?
答案 1 :(得分:3)
显然不是。标准(14.8.2.5)称这是一个非推断的背景;
但是,在某些情况下,该值不参与类型推导,而是使用模板参数的值,这些参数可以在其他地方推断或明确指定。
...
未推断的上下文是:
...
- 一个函数参数,其关联参数是初始化列表(8.5.4),但该参数没有std :: initializer_list或对可能的cv-quali fi ed std :: initializer_list类型的引用。
示例:
模板&lt; class T&gt; void g(T);
的参数
克({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
的大小不是模板参数,我想不出一种方法可以从中推导和转发数组 size initializer_list
的方式与类型相同。
答案 2 :(得分:2)
你可以直接使用初始化列表来实现该语法。 e.g:
#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) {
...
答案 3 :(得分:0)
可以引用原始数组:
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
。