yohhoyの日記

技術的メモをしていきたい日記

関数パラメータ型としてのauto?

gcc(g++) 4.9.0以降/gnu++1zモードでは、関数パラメータ型として auto キーワードを利用できる。これはC++1zに向けて提案されているConcepts Lite拡張の一部。

2019-01-09追記:C++2a(C++20)言語仕様に向けて、abbreviated function template 構文を含むP1141R2が採択された。同提案は関数テンプレートへのコンセプト制約指定が主目的だが、同構文の自然な拡張(コンセプト制約の省略形)として導入される。

2017-09-02追記:発行済み ISO/IEC TS 19217:2015(Concepts TS) には同仕様が含まれるが、C++2aに向けたP0696R0にて abbreviated function template はConcepts仕様から削除された。C++2aでは(PDF)P0734R0を統合予定となっており、C++標準規格としては同機能はサポートされない。

// g++ -std=gnu++1z(Concepts Lite)
void f(auto v)  // ??
{
  std::cout << v;
}
// 下記と等価:
// template <typemame T> void f(T v) {... }

f(42);
f("hello");

なおConcepts Lite拡張でなくても、C++14で導入されたジェネリックラムダ(generic lambda)により、ラムダ式パラメータ型としてなら auto を利用できる。

// C++14
auto f = [](auto v)
{
  std::cout << v;
};

(PDF)N4361 Working Draft, C++ extensions for Concepts, 7.1.6.4/p3変更, 8.3.5/p16-18追加の記述より、N4361適用後の仕様文面として該当箇所引用(下線部は強調)。

Modify paragraph 3 to allow the use of auto within the parameter type of a lambda or function.

3 If a placeholder appears in a parameter type of a lambda-expression, the lambda is a generic lambda (5.1.2). (snip) Similarly, if a placeholder appears in a parameter type of a function declaration, the function declaration declares an abbreviated function template (8.3.5). [Example:

void f(const auto&, int);
  // OK: an abbreviated function template

--end example]

Add the following paragraphs after paragraph 15.

16 An abbreviated function template is a function declaration whose parameter-type-list includes one or more placeholders (7.1.6.4). An abbreviated function template is equivalent to a function template (14.6.6) whose template-parameter-list includes one invented template-parameter for each occurrence of a placeholder in the parameter-declaration-clause, in order of appearance, according to the rules below.
17 Each template parameter is invented as follows.

  • If the placeholder is designated by the auto type-specifier, then the corresponding invented template parameter is a type template-parameter.
  • (snip)

18 (snip) [Example:

template<typename T> class Vec { };
template<typename... Args> class Tuple { };

void f1(const auto&, auto);
void f2(Vec<auto*>...);
void f3(Tuple<auto...>);
void f4(auto (auto::*)(auto));

template<typename T, typename U>
  void f1(const T&, U);   // redeclaration of f1
template<typename... T>
  void f2(Vec<T*>...);    // redeclaration of f2
template<typename... Ts>
  void f3(Tuple<Ts...>);  // redeclaration of f3
template<typename T, typename U, typename V>
  void f4(T (U::*)(V));   // redeclaration of f4
//...

--end example] (snip)

関連URL