6

C++11 で、次のようなことはできますか?

template<typename T, size_t N>
void foo(array<T, N> src) { ... }

...

foo({1, 2, 3})

現在、GCC 4.8 を実行しています。

4

4 に答える 4

7

はい、次の作業を行うことができました (似たようなものを許可したため):

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_arrayC配列の初期化をエミュレートする方法 “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 のテンプレート引数ではないのはなぜですか?

于 2013-06-30T10:54:40.253 に答える
3

どうやらそうではありません。標準 (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::vectorinitializer_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

于 2013-06-30T08:10:28.417 に答える