函子operator()的条件专门化
Conditional specialization of functors operator()
我想请您帮助我解决最近几天遇到的编程难题。让我试着解释一下我要实现什么…
我的目标是定义一组具有其有效性的方程。让我更详细地解释一下……
我认为每个方程对象都是一个函子——一个定义operator()
的类。该运算符的定义应针对每种方程类型进行专门化。专门化包含计算本身:
. h:
enum class IDs : int { A = 0, B = 1, C = 2 };
template<IDs WHICH>
struct Equation
{
int operator() ( void );
}
. cpp:
template<>
Equation<IDs::A>::operator()( void )
{
/* Just some sample equation */
return( 42 + 28 );
}
您可能已经注意到,特化是由enum类成员id定义的::?
这似乎是工作。但我想添加所谓的可用性特征-该方程可能仅对某些用户对象类型有效。
There is 'validity group' declared:
/* Object types declaration */
namespace Objects {
using Object0 = boost::mpl::int_<0>;
using Object1 = boost::mpl::int_<1>;
using Object2 = boost::mpl::int_<2>;
}
/* Validity groups declaration */
using ValidityGroup1 = boost::mpl::vector<Object0, Object2>;
using ValidityGroup2 = boost::mpl::vector<Object1>;
我使用以下构造来使类启用或禁用(使用boost::enable_if)。我来演示一下如何使用它:
template<typename TYPE_LIST, typename QUERY_TYPE>
struct IsTypeInList
{
using TypePos = typename boost::mpl::find<TYPE_LIST, QUERY_TYPE>::type;
using Finish = typename boost::mpl::end<TYPE_LIST>::type;
using type = typename boost::mpl::not_<boost::is_same<TypePos, Finish> >::type;
using value_type = typename type::value_type;
static const bool value = type::value;
};
template<typename OBJECT_TYPE, typename ENABLER=void>
class SampleClass;
template<typename OBJECT_TYPE>
class SampleClass<OBJECT_TYPE, typename boost::enable_if<typename IsTypeInList<ValidityGroup1, Object0>::type>::type>
{}
SampleClass的部分专门化只有在Object0
属于ValidityGroup1
时才可用。到目前为止一切顺利。验证了该原理。
现在有趣的事情来了。我想把这两件事合并在一起:
目标:
定义等式的操作符()谁的专门化包含有效的主体是由id定义的::?? ?enum类值",只适用于属于ValidityGroup的Object…可以对相同的id进行另一次计算::?? ?但对其他ValidityGroup中的Object有效(即Object0的属性计算方式与Object1不同)
我知道整个概念相当复杂,可能令人困惑。让我展示一下我实现这些东西的尝试:
template<typename OBJECT_TYPE, typename VALIDITY_GROUP, IDs ID, typename ENABLER = void>
class Equation;
template<typename OBJECT_TYPE, typename VALIDITY_GROUP, IDs ID>
class Equation<OBJECT_TYPE, VALIDITY_GROUP, ID, typename boost::enable_if<typename IsTypeInList<VALIDITY_GROUP, OBJECT_TYPE>::type>::type >
: public EquationBase<IDs>
{
public:
int operator() ( void );
};
template<typename OBJECT_TYPE, typename VALIDITY_GROUP, IDs ID>
int Equation<OBJECT_TYPE, ValidityGroup1, Ids::A>::operator() ( void )
{
return( 42 + 56 );
}
但是operator()定义不起作用…你能告诉我如何使它工作吗?或者有人有其他的想法如何实现上面写的目标吗?
提前感谢任何愿意帮助我的人
欢呼马丁
编辑:公式在模板类对象中使用。让代码解释:
template<typename OBJECT_TYPE>
class Object
{
public:
Object( void );
};
. cpp:
template<typename OBJECT_TYPE>
Object<OBJECT_TYPE>::Object( void )
{
std::cout << Equation<IDs::A>()() << std::endl;
}
问题是当操作符()被特化时,OBJECT_TYPE没有定义…
如果我理解正确的话,我想有很多方法。
下面是一个简单的示例(但完整且有效),展示了如何使用操作符
的返回类型使用std::enable_if
(但boost::enable_if
应该是可以的)选择不同的实现#include <iostream>
#include <type_traits>
template <typename ObjT, typename ValT>
class Equation
{
public:
template <typename X = ObjT>
typename std::enable_if<true == std::is_same<X, ValT>::value, int>::type
operator() ( void )
{ return( 0 ); }
template <typename X = ObjT>
typename std::enable_if<false == std::is_same<X, ValT>::value, int>::type
operator() ( void )
{ return( 1 ); }
};
int main()
{
Equation<int, int> eq0;
Equation<int, long> eq1;
std::cout << "eq0 val: " << eq0() << std::endl; // print "eq0 val: 0"
std::cout << "eq1 val: " << eq1() << std::endl; // print "eq1 val: 1"
}
不是很优雅,我想。
另一个解决方案(我认为,最适合您的需要)可能是基于类部分专门化
#include <iostream>
#include <type_traits>
template <typename ObjT, typename ValT, bool = std::is_same<ObjT, ValT>::value>
class Equation;
template <typename ObjT, typename ValT>
class Equation<ObjT, ValT, true>
{
public:
int operator() ();
};
template <typename ObjT, typename ValT>
class Equation<ObjT, ValT, false>
{
public:
int operator() ();
};
template <typename ObjT, typename ValT>
int Equation<ObjT, ValT, true>::operator() ()
{ return( 0 ); }
template <typename ObjT, typename ValT>
int Equation<ObjT, ValT, false>::operator() ()
{ return( 1 ); }
int main()
{
Equation<int, int> eq0;
Equation<int, long> eq1;
std::cout << "eq0 val: " << eq0() << std::endl; // print "eq0 val: 0"
std::cout << "eq1 val: " << eq1() << std::endl; // print "eq1 val: 1"
}
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 在没有太多条件句的情况下,我如何避免被零除
- 基于多个条件处理地图中的所有元素
- 条件constexpr函数
- 无论条件是否为true,if总是在c++中执行
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 基于模板值的条件变量
- 是否可以对零模板参数进行模板专门化
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 将按位if条件转换为普通if条件
- 条件断点在不应该触发时触发
- 为什么简单的算术减法在"if"条件下不起作用?
- 如何在for循环中包含两个索引值的测试条件
- 如果条件为TRUE(最佳方式?),则在do while循环中后置增量
- 我提出什么条件才能再加5%的折扣
- 循环中的条件:为什么每次都调用strlen(),而vector.size()只调用一次
- 即使没有满足他们的条件,我也无法通过一些 do-while 循环
- 如何编写一个使用n倍三元条件语句的C++布尔函数
- 没有超时的C++条件变量
- 函子operator()的条件专门化