将模板 class is_convertible 特化为众所周知的类型
Specialise functor when template class is_convertible to a well known type
所以我想在模板类型 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
时做一些事情,而在不能转换为 WellKnownType
时什么都不做:
template <typename T>
class Foo {
public:
Foo() {
my_functor<T>()(m_t);
}
T m_t;
};
我不知道如何实现这种行为。我知道 BOOST_CONCEPT_REQUIRES
,但不知道如何将其应用于模板专业化。有帮助吗?
你可以用你的仿函数做一些事情
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"; }
};
只是为了完整性,做了一些研究,我最终也使用 std::enable_if
和 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";
}
既然你标记了这个 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>>;
所以我想在模板类型 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
时做一些事情,而在不能转换为 WellKnownType
时什么都不做:
template <typename T>
class Foo {
public:
Foo() {
my_functor<T>()(m_t);
}
T m_t;
};
我不知道如何实现这种行为。我知道 BOOST_CONCEPT_REQUIRES
,但不知道如何将其应用于模板专业化。有帮助吗?
你可以用你的仿函数做一些事情
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"; }
};
只是为了完整性,做了一些研究,我最终也使用 std::enable_if
和 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";
}
既然你标记了这个 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>>;