gcc(g++) 4.9.0以降/gnu++1zモードでは、関数パラメータ型として auto キーワードを利用できる。これはC++1zに向けて提案されているConcepts Lite拡張の一部。
2019-01-11追記:C++2a(C++20)言語仕様に向けて、abbreviated function template 構文を含むP1141R2が採択された。同提案は関数テンプレートへのコンセプト制約指定が主目的だが、同構文の自然な拡張(コンセプト制約の省略形)として導入される。id:yohhoy:20190111 参照。
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