2014-05-22 49 views
1

我想定義一個類模板,該模板需要對正在定義的類的實例進行操作的函數模板參數。需要函數模板參數的類模板,該函數模板參數對正在定義的類的實例進行操作

這是或類似的事情嗎?

我知道我可以定義轉換構造函數,但是由於這個簡化示例中不清楚的原因,我希望能夠改變類的功能而不更改其定義或創建派生類型。

我知道我可以包含函數指針成員並使用setter來修復它們的功能,但我寧願使用聲明性typedef而不是以編程方式修復該類的功能。

template 
    < typename T 
    , MyClass<X> (to_X)(MyClass<T>) 
    , MyClass<T> (from_X)(MyClass<X>) 
    > 
class MyClass { 

    T value; 

    MyClass(T v) : value(v) {} 

    // is it possible to use to_X and from_X template args 
      // to declare member functions ... 
} 

MyClass<int> to_int(MyClass<std::string> value) { 

    // return result of conversion 
} 

MyClass<std::string> to_string(MyClass<int> value) { 

    // return result of conversion 
} 

MyClass<std::string, to_string, to_int> foo1 = 
     MyClass<std::string, to_string, to_int>("5"); 

MyClass<int, to_int, to_string> * foo2 = foo1.to_int(); 

回答

0

我建議你使用策略類的方法:你的類模板參數化有兩個轉換政策

template<typename T, 
     typename FROM, 
     typename TO 
     > 
class MyClass 
{ 
    FROM from_t_conversion; 
    TO to_t_conversion; 

    MyClass() = default; 

    template<typename U> 
    operator U() const 
    { 
     return from_t_conversion(*this); 
    } 

    template<typename U> 
    MyClass(const U& u) : MyClass() 
    { 
     std::swap(*this , to_t_conversion(u)); 
    } 
}; 

這種設計的點是一個轉換的策略類型(表格) :A轉換策略可以是與所期望的簽名任何調用實體:一個函數,一個仿函數,一個拉姆達等

編輯:這裏是轉換器的一個例子:

struct float_to_int 
{ 
    MyClass<itn> operator()(const MyClass<float>&) 
    { 
     return MyClass<int>{}; 
    } 
}; 

//A more generic conversion function: 
template<typename T> 
struct generic_to_converter 
{ 
    template<typename U , typename X = T> 
    MyClass<X> operator()(const MyCLass<U>&) 
    { 
     return /* something /* 
    } 
}; 
+0

如何執行的模板參數重疊typeness即T = int和TO = INT(串) – user3666939

+0

@ user3666939不強制它。只能通過與T協同工作的策略。這是一種常見模式,請參閱標準容器的分配器,例如 – Manu343726

+0

,您可以提供FROM和TO的示例定義。我很困惑,因爲我不知道如何根據MyClass 來定義FROM或TO。 – user3666939

0

也許不overthink這一點,並保持它的簡單:

template <typename T, typename Converter> 
class MyClass 
{ 
    T value; 
    Converter converter; 

public: 
    explicit MyClass(T const & v, Converter const & c = Converter()) 
    : value(v), converter(c) 
    { } 

    template <typename U, typename C = Converter> 
    operator MyClass<U, C>() const 
    { 
     return converter.template convert<U, C>(*this); 
    } 
}; 

你的轉換器需要這個樣子:

struct ExampleConverter 
{ 
    template <typename U, typename C1, typename T, typename C2> 
    MyClass<U, C1> convert(MyClass<T, C2> const &) const; 
}; 

用多一點點的努力,你可以採取基類佈局優化的優點(與標準庫實現通常處理分配器和比較器的方式相同)。


你也可以有一些rebind機制讓轉換器本身成爲一個模板。

template <typename T, typename Converter = StandardConverter<T>> 
class MyClass 
{ 
    T value; 
    Converter converter; 

public: 
    explicit MyClass(T const & v, Converter const & c = Converter()) 
    : value(v), converter(c) 
    { } 

    template <typename U, 
       typename C = typename Converter::template rebind<U>::type> 
    operator MyClass<U, C>() const 
    { 
     return converter.template convert<U, C>(*this); 
    } 
}; 

template <typename T> 
struct StandardConverter 
{ 
    template <typename U, typename C> 
    MyClass<U, C> convert(MyClass<T, StandardConverter<T>> const &) const; 

    template <typename U> struct rebind { using type = StandardConverter<U>; }; 
}; 
+0

[現場演示](http://ideone.com/BZj2db) –

相關問題