4

所以我想在模板类型时应用特定的boost::is_convertible代码WellKnownType

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,但不知道如何将其应用于模板专业化。有什么帮助吗?

4

3 回答 3

4

您可以使用仿函数执行以下操作

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

于 2015-09-20T03:58:55.627 回答
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>;

或者,您可以使用 type trait 为两个完全不相关的仿函数类型之一设置别名:

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>>; 
于 2015-09-20T09:19:38.427 回答
-1

只是为了完整起见,进行了一些研究,我最终也使用了这个选项std::enable_ifand std::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";
}
于 2015-09-20T04:05:37.740 回答