2015-09-20 21 views
3

所以我想申請特定的代碼時,模板類型boost::is_convertibleWellKnownType專營仿函數時,模板類is_convertible到一個衆所周知的類型

template <typename T> 
class Foo { 
public: 
    Foo() { 
     // apply specific function to m_t 
     // if T is convertible to WellKnownType 
    } 
    T m_t; 
}; 

對於這一點,我想使用一個函子:

template <typename T> 
struct my_functor { 
    void operator()(T& t) { 
     // do nothing by default 
    } 
}; 

然後,我想專門函子做別的事情的時候boost::is_convertible<T, WellKnownType>

template <> 
struct my_functor<...> { 
    void operator()(T& t) { 
     // do something to t because it is convertible to WellKnownType 
    } 
}; 

然後,我想我可以很容易地改變Foo定義中使用的函子,做東西的時候T可以轉換爲WellKnownType和一籌莫展的時候,它是不是:

template <typename T> 
class Foo { 
public: 
    Foo() { 
     my_functor<T>()(m_t); 
    } 
    T m_t; 
}; 

我不知道的是如何實現這種行爲。我知道BOOST_CONCEPT_REQUIRES,但不知道如何將其應用於模板專業化。任何幫助?

回答

3

你可以不喜歡你的算符以下

template<typename T, typename WellKnownType > 
struct my_functor 
{ 
    void operator()(const T& x) { 
     myopImpl(x, boost::is_convertible<T, WellKnownType>()); 
    } 

    void myopImpl(T const& x, boost::false_type) 
    { std::cout << "Some Other Stuff \n"; } 

    void myopImpl(T const& x, boost::true_type) 
    { std:: cout << "Some Specific Stuff \n"; } 

}; 

Demo here

+0

這將做。謝謝! – alesegdia

-1

只是爲了保持完整性,做一些研究,我結束了也該選項使用std::enable_ifstd::is_base_of

template <typename T> 
void do_it(typename std::enable_if<std::is_base_of<WellKnownType, T>::value, T>::type& t) 
{ 
    std::cout << "Specific code\n"; 
} 

... 

template <typename T> 
void do_it(typename std::enable_if<!std::is_base_of<WellKnownType, T>::value, T>::type& t) 
{ 
    std::cout << "Generic code\n"; 
} 
+3

如果你真的嘗試了這個,你會注意到它不起作用。 'T'是在一個非推導的上下文中。 –

+0

我嘗試了它作爲免費功能,它確實如此,我只是爲了確定而更改代碼。謝謝。 – alesegdia

+0

@ T.C。它的工作原理如下:http://coliru.stacked-crooked.com/a/faf79b578160f716 – alesegdia

3

由於您標記了此C++ 11,因此您應該使用標準庫類型特徵而不是Boost特徵。此外,還可以部分地專注於一種特質 - 它只是成爲另一個模板參數:

template<typename T, typename WellKnownType, typename = void> 
struct my_functor 
{ 
    void operator()(T const& x) { 
     // generic code 
    } 
}; 

template <typename T, typename WellKnownType> 
struct my_functor<T, WellKnownType, 
    std::enable_if_t<std::is_convertible<T, WellKnownType>::value> 
    > 
{ 
    void operator()(T const& x) { 
     // specific code if convertible 
    } 
}; 

如果你不喜歡的第三個參數的外觀,你可以把一個名稱空間,然後簡單地添加:

template <typename T, typename WellKnownType> 
using my_functor = details::my_functor<T, WellKnownType>; 

或者,您可以使用類型性狀別名兩個完全不相干的仿函數類型之一:

template <typename T, typename WellKnownType> 
using my_functor = std::conditional_t< 
    std::is_convertible<T, WellKnownType>::value, 
    my_functor_specific<T>, 
    my_functor_generic<T>>;