2017-03-08 3 views
0

私は、別の型Tを与えられた記憶域タイプを指定するテンプレートを定義しようとしています。すべての算術型をcatchするためにenable_ifを使いたいと思います。以下は、テンプレートが2つのパラメータで再宣言されるという私の試みです。プライマリテンプレートに2番目のダミーのparmを追加しようとしましたが、別のエラーが発生しました。これはどうすればできますか?構造体特化でenable_ifを使用する

#include <string> 
#include <type_traits> 
template <typename T> struct storage_type; // want compile error if no match 
// template <typename T, typename T2=void> struct storage_type; // no joy 
template <> struct storage_type<const char *> { typedef std::string type; }; 
template <> struct storage_type<std::string> { typedef std::string type; }; 
template <typename T, typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr> 
    struct storage_type { typedef double type; }; 

// Use the storage_type template to allocate storage 
template<typename T> 
class MyStorage { 
    public: 
    typename storage_type<T>::type storage; 
}; 

MyStorage<std::string> s; // uses std::string 
MyStorage<const char *> s2; // uses std::string 
MyStorage<float> f; // uses 'double' 
+0

'long double'は' double'より大きくなることに注意してください。また、 'long long'は最低64ビットですが、それよりも大きくなる可能性があります。 – NathanOliver

+0

[はっきりとしたもの](http://coliru.stacked-crooked.com/a/5c085b6a1f9b5a20)を最初に修正しますか? –

+0

@πάνταῥεῖ私は彼が求めていること、そのエラーを解決する方法を信じています。 –

答えて

5

第2パラメータをプライマリテンプレートに追加し、それに合わせて特化することでこれを行うことができます。あなたは正しい軌道に乗っていたが、それを正しくしなかった。

#include <string> 
#include <type_traits> 
// template <typename T> struct storage_type;    // Don't use this one. 
template <typename T, typename T2=void> struct storage_type; // Use this one instead. 
template <> struct storage_type<const char *> { typedef std::string type; }; 
template <> struct storage_type<std::string> { typedef std::string type; }; 

// This is a partial specialisation, not a separate template. 
template <typename T> 
struct storage_type<T, typename std::enable_if<std::is_arithmetic<T>::value>::type> { 
    typedef double type; 
}; 

// Use the storage_type template to allocate storage 
template<typename T> 
class MyStorage { 
    public: 
    typename storage_type<T>::type storage; 
}; 

MyStorage<std::string> s; // uses std::string 
MyStorage<const char *> s2; // uses std::string 
MyStorage<float> f; // uses 'double' 

// ----- 

struct S {}; 

//MyStorage<S> breaker; // Error if uncommented. 

And voila

関連する問題