我有一个“参数”类,可选择将“标识组类型”作为模板参数typename IDENTIFICATION_GROUP
保存:
struct ConstrainedParameterIdentification_None {};
template<typename UNIT_TYPE, typename DATA_TYPE = double, typename IDENTIFICATION_GROUP = ConstrainedParameterIdentification_None>
class Parameter
{
/* Constructor - the only method taking care about valid IDENTIFICATION_GROUP */
template<typename = std::enable_if<!std::is_same<IDENTIFICATION_GROUP, ConstrainedParameterIdentification_None>::value>>
Parameter( const typename IDENTIFICATION_GROUP::IDType ID )
{ /* ... */ }
};
在使用Parameter类时,会使用下面列出的类型(interresting part为using IDType = int;
):
struct SampleIdentificationGroup
{
using IDType = int;
/* ... */
};
除非我像这样实例化参数:
Parameter<si::length, double, SampleIdentificationGroup> Param;
一切都运转良好。
但是,一旦我想使用默认值IDENTIFICATION_GROUP
- ConstrainedParameterIdentification_None
,就会遇到麻烦。我的第一次尝试是简单地在IDType
中定义ConstrainedParameterIdentification_None
,但由于副作用,它不是解决方案。因此,我想使用IDENTIFICATION_GROUP
“internals(typedefs ...)”启用/禁用参数成员方法。
所以我尝试应用SFINAE来启用/禁用我的构造函数(唯一关注IDENTIFICATION_GROUP
“内部构件的方法):
template<typename = std::enable_if<!std::is_same<IDENTIFICATION_GROUP, ConstrainedParameterIdentification_None>::value>>
Parameter( const typename IDENTIFICATION_GROUP::IDType ID )
{ /* ... */ }
在人类语言中,我想要触及的是“如果 IDENTIFICATION_GROUP
ConstrainedParameterIdentification_None
,请排除整个方法。< /强>”。
但是GCC抱怨没有定义类型IDType:
error: no type named ‘IDType’ in ‘struct Base::ConstrainedParameterIdentification_None’
Parameter( const typename IDENTIFICATION_GROUP::IDType ID )
但由于SFINAE,构建中应省略Parameter( const typename IDENTIFICATION_GROUP::IDType ID )
,对吧?那么为什么这么抱怨呢?我做错了什么?
非常感谢任何愿意帮助的人......
干杯马丁
答案 0 :(得分:2)
我想您可以按照以下方式编写构造函数
template <typename IG = IDENTIFICATION_GROUP>
Parameter (typename std::enable_if<false == std::is_same<IG, ConstrainedParameterIdentification_None>::value, typename IG::IDType>::type const ID)
{ /* ... */ }
如果你可以使用C ++ 14,那么std::enable_it_t
应该避免一个令人讨厌的typename
和一个annoing ::type
,所以
template <typename IG = IDENTIFICATION_GROUP>
Parameter (std::enable_if_t<false == std::is_same<IG, ConstrainedParameterIdentification_None>::value, typename IG::IDType> const ID)
{ /* ... */ }
答案 1 :(得分:1)
问题在于您尝试将不存在的类型传递给std::enable_if
。要解决这个问题,您可以轻松地提出自己的enable_if版本:
template <typename IDENTIFICATION_GROUP = ConstrainedParameterIdentification_None> struct my_enable_if {
using type = typename IDENTIFICATION_GROUP::IDType;
};
template <> struct my_enable_if<ConstrainedParameterIdentification_None> {
};
template<typename IDENTIFICATION_GROUP = ConstrainedParameterIdentification_None> class Parameter {
public:
template <typename Unused = IDENTIFICATION_GROUP>
Parameter(typename my_enable_if<Unused>::type ID) { }
Parameter() { }
};
虚拟Unused
模板参数是SFINAE工作所必需的(有问题的方法必须至少依赖于一个模板参数)。