5

このコード:

#include <memory>

template <template <typename> class Ptr>
class A { Ptr<int> ints; };

using B = A<std::unique_ptr>;

次のエラーが発生します (GCC 6.3 の場合):

a.cpp:6:28: error: type/value mismatch at argument 1 in template parameter list for ‘template<template<class> class Ptr> class A’
 using B = A<std::unique_ptr>;
                            ^
a.cpp:6:28: note:   expected a template of type ‘template<class> class Ptr’, got ‘template<class _Tp, class _Dp> class std::unique_ptr’

これで、次のように回避できます。

template <typename T>
using plugged_unique_ptr = std::unique_ptr<T>;
using B = A<plugged_unique_ptr>;

しかし、なぜ私はしなければならないのですか?つまり、コンパイラが の 2 番目のテンプレート パラメータをstd::unique_ptrデフォルト値で「プラグ」しstd::unique_ptrて、 のテンプレート引数として使用できるようにしないのはなぜAでしょうか?

4

3 に答える 3

6

テンプレート テンプレート パラメータは正確に一致する必要があるためです。これは、デフォルトのテンプレート引数がここでは関係ないことを意味します。テンプレート引数を 2 つのテンプレート引数に拡張することは、偶然にしか機能しないことに注意してください: 実装は、標準で定義されているよりも多くのテンプレート引数を追加することが許可されており、std コンテナーの周りの SFINAE の場合によく行われます。

これは、私が通常、テンプレートのテンプレート引数を使用しないことをお勧めする主な理由でもあり、代わりに単純なテンプレートの型名を使用するだけです。ネストされたテンプレート タイプにアクセスする必要がある場合は、eg の行で内部アクセサーを提供するか、テンプレート内でこれらにアクセスするvalue_typeなどの外部アクセサーを提供します。tuple_element


注:これは明らかに C++17 で変更されており、マッチングは正確ではなくなりましたが、少し緩和されましたが、より複雑になりました。それにもかかわらず、一般的にはテンプレート テンプレート パラメーターを使用しないことをお勧めします。

于 2018-07-16T08:43:05.253 に答える