web-dev-qa-db-ja.com

C ++ 17のテンプレートパラメーターの自動の利点

(おそらく)C++ 17で導入されるテンプレートパラメータのautoの利点は何ですか?

テンプレートコードをインスタンス化する場合、それはautoの自然な拡張機能ですか?

auto v1 = constant<5>;      // v1 == 5, decltype(v1) is int
auto v2 = constant<true>;   // v2 == true, decltype(v2) is bool
auto v3 = constant<'a'>;    // v3 == 'a', decltype(v3) is char

この言語機能から他に何が得られますか?

50
Damian

template <auto>機能( P0127R1 )は、フィンランドのオウルで開催されたISO C++ 2016ミーティングでC++に受け入れられました。

テンプレートパラメータのautoキーワードを使用して、インスタンス化の時点で型が推定される非型パラメータを示すことができます。これをより便利な記述方法と考えると役立ちます。

template <typename Type, Type value>

例えば、

template <typename Type, Type value> constexpr Type constant = value;
constexpr auto const IntConstant42 = constant<int, 42>;

今のように書くことができます

template <auto value> constexpr auto constant = value;
constexpr auto const IntConstant42 = constant<42>;

明示的にタイプを入力する必要はありません。 P0127R1 には、template <auto>可変長テンプレートパラメータを使用すると、非常に便利です。たとえば、コンパイル時リストの定数値を実装する場合などです。

template <auto ... vs> struct HeterogenousValueList {};
using MyList1 = HeterogenousValueList<42, 'X', 13u>;

template <auto v0, decltype(v0) ... vs> struct HomogenousValueList {};
using MyList2 = HomogenousValueList<1, 2, 3>;

C++ 1z以前では、HomogenousValueListは単に次のように記述できました。

template <typename T, T ... vs> struct Cxx14HomogenousValueList {};
using MyList3 = Cxx14HomogenousValueList<int, 1, 2, 3>;

HeterogenousValueListに相当するものを書くことは、他のテンプレートで値をラップすることなしには不可能です。たとえば:

template <typename ... ValueTypes> struct Cxx14HeterogenousValueList {};
using MyList4 = Cxx14HeterogenousValueList<constant<int, 42>,
                                           constant<char, 'X'> >;
57
mceo

実際、mceoの(元の)回答の実際の値の場合は、非型テンプレートパラメーターとして明示的にカバーされていません。

template <auto ... vs> struct HeterogenousValueList {};
using MyList1 = HeterogenousValueList<42, 'X', 1.3f>;

言及された提案で与えられた例を参照してください:§14.3.2パラグラフ2を修正してください

template<auto n> struct B { /* ... */ };
B<5> b1;   // OK: template parameter type is int
B<'a'> b2; // OK: template parameter type is char
B<2.5> b3; // error: template parameter type cannot be double

数日前に同じ誤解につまずいた。

10
m-j-w

ここに別の例があります(@ Rakete1111によって最初に提示された 不明なタイプのテンプレートテンプレートパラメーター ):

タイプを知らずにSIZEの値を抽出する:

template<std::size_t SIZE>
class Foo {};

template <template<auto> class T, auto K>
auto extractSize(const T<K>&) {
    return K;
}

int main() {
    Foo<6> f1;
    Foo<13> f2;
    std::cout << extractSize(f1) << std::endl;
    std::cout << extractSize(f2) << std::endl;
}
4
Amir Kirsh