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 でコンパイラに渡されるオプションを理解できなかったので、そのサイトを断念しました。
@Pavel Minaevの回答から、make_array
C配列の初期化をエミュレートする方法 “int arr[] = { e1, e2, e3, … }” の動作を std::array で恥知らずに盗みましたか? 質問。他の提案により、修正できなかったコンパイル エラーが発生しました。make_array
このmake_array
機能には制限があります。投稿全体をお読みください。特に議論std::array - comp.lang.c++.moderated でのサイズを知っていれば参照されます。どうやら、合理的なものを得るのmake_array
は非常に難しいようです。この回答の素朴な人を本番コードで使用することはお勧めしません。make_array
サイズが へのテンプレート引数である場合、問題はありませんstd::initializer_list
。したがって、サイズが std::initializer_list のテンプレート引数ではないのはなぜですか?
どうやらそうではありません。標準 (14.8.2.5) では、これを非推定コンテキストと呼んでいます。
ただし、特定のコンテキストでは、値は型推定に参加せず、代わりに他の場所で推定された、または明示的に指定されたテンプレート引数の値を使用します。
...
非推定コンテキストは次のとおりです。
...
- 関連する引数がイニシャライザ リスト (8.5.4) であるが、パラメータに std::initializer_list または cv 修飾された可能性のある std::initializer_list 型への参照がない関数パラメータ。
例:
template<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