質問:どの専門技術を使用してfoo<std::unique_ptr<int>>
と呼ぶべきですか?
int
はクラスではないので、値std::is_class<T>::value
はfalseであり、A
のバージョンは一致しません。
あなたはA
バージョンが今まで使用されていることをしたい場合は、最初のテンプレートパラメータがstd::unique_ptr
あるとき、あなたは
template <typename T>
struct foo<std::unique_ptr<T>,
typename std::enable_if<std::is_class<
std::unique_ptr<T>>::value>::type>
{ static int const value = 1; };
または
template <typename T,
typename = typename std::enable_if<std::is_class<T>::value>::type>
struct foo;
template <typename T>
struct foo<std::unique_ptr<T>>
{ static int const value = 1; };
template <typename T>
struct foo<T>
{ static int const value = 2; };
を次のように
foo
を書くことができるよう
A
バージョンを書くことができます
したがってA
はB
よりも特殊なバージョンになり、コードをコンパイルできます。さもなければ、A
のあなたのバージョンは実際にはB
ですが、コンパイラはそれを認識しないより特殊なバージョンです。
template <typename T>
struct foo<std::unique_ptr<T>,
typename std::enable_if<std::is_class<
std::unique_ptr<T>>::value>::type>
{ static int const value = 1; };
コードのコンパイルとそれを観察し、std::is_class<std::unique_prt<T>>::value
はこれまで真であること。しかし、あなたは
template <typename T>
struct foo<std::unique_ptr<T>,
typename std::enable_if<true>::type>
{ static int const value = 1; };
(つまり、実際には、同等である)書く場合のコードは、
をコンパイルしていません - EDIT -
あなたはそのfoo<std::unique_ptr<int>
マッチケースB
をしたい場合は、あなたは(例で)
struct foo<T>
{ static int const value = 2; };
template <typename T>
struct proValue
: std::integral_constant<int, 2>
{ };
template <typename T>
struct proValue<std::unique_ptr<T>>
: std::integral_constant<int, std::is_class<T>::value ? 1 : 2>
{ };
を次のようにタイプの特性を作成し、foo
などを定義することができます以下は、アンリは、彼の答えに言ったことに加えて、完全なコンパイルの例
#include <memory>
#include <vector>
#include <iostream>
#include <type_traits>
class Test
{ };
template <typename T,
typename = typename std::enable_if<std::is_class<T>::value>::type>
struct foo;
template <typename T>
struct foo<std::unique_ptr<T>>
{ static int const value = 1; };
template <typename T>
struct foo<T>
{ static int const value = 2; };
template <typename T>
struct proValue
: std::integral_constant<int, 2>
{ };
template <typename T>
struct proValue<std::unique_ptr<T>>
: std::integral_constant<int, std::is_class<T>::value ? 1 : 2>
{ };
template <typename T, int = proValue<T>::value>
struct bar;
template <typename T>
struct bar<std::unique_ptr<T>, 1>
{ static int const value = 1; };
template <typename T>
struct bar<T, 2>
{ static int const value = 2; };
int main()
{
std::cout << foo<std::vector<int>>::value << '\n'; // print 2
std::cout << foo<std::unique_ptr<int>>::value << '\n'; // print 1
std::cout << foo<std::unique_ptr<Test>>::value << '\n'; // print 1
std::cout << bar<std::vector<int>>::value << '\n'; // print 2
std::cout << bar<std::unique_ptr<int>>::value << '\n'; // print 2
std::cout << bar<std::unique_ptr<Test>>::value << '\n'; // print 1
}
まあ、2つの 'std :: enable_if'ステートメントは補完的なものでしょうか? –
それはそれを解決するかもしれませんが、私の理解は、 "より特殊化された"ルールは不要にする必要があります。 – Arelius