问题描述
|
我正在寻找一个相对通用的:
尝试编译此行代码
如果成功,请编译并使用该行代码。除此以外
使用其他代码行
我想根据提供的函子是否在ѭ0上有效来选择性地编译某些内容:
//Some user supplied functor I can\'t modify which works on `int` but not `double`
template<typename T>
struct LShift : std::binary_function<T,T,T>
{
T operator()(T lhs,T rhs)
{
return lhs << rhs;
}
};
//Class that holds either an int or a double
class Example
{
union
{
int intVal;
double dblVal;
} value;
bool isIntType;
public:
Example(int val)
: isIntType(true)
{
value.intVal = val;
}
Example(double val)
: isIntType(false)
{
value.dblVal = val;
}
int GetIntergalValue() const
{
return value.intVal;
}
double GetDoubleValue() const
{
return value.dblVal;
}
bool IsIntegral() const
{
return isIntType;
}
};
//Does something with an example. I kNow that if the examples have `double` contents,//that the functor passed will also be valid for double arguments.
template <template <typename Ty> class FunctorT>
Example DoSomething(const Example& lhs,const Example& rhs)
{
if (lhs.IsIntergal() != rhs.IsIntergal())
{
throw std::logic_error(\"...\");
}
if (lhs.IsIntegral())
{
return Example(FunctorT<int>(lhs.GetIntergalValue(),rhs.GetIntergalValue()));
}
else
{
return Example(FunctorT<double>(lhs.GetDoubleValue(),rhs.GetDoubleValue()));
}
}
int main()
{
DoSomething<LShift>();
}
我以前从未使用过SFINAE,但这是我的第一次尝试:
template <template <typename Ty> class FunctorT>
double Dodouble(double lhs,double rhs)
{
return FunctorT<double>()(lhs,rhs);
}
template <template <typename Ty> class FunctorT>
double Dodouble(int lhs,int rhs)
{
throw std::logic_error(\"That is not valid on floating types.\");
}
我认为替换将在第一个重载上失败(之所以选择它,是因为通过双打时它是更好的重载),然后该控制将继续进行第二个重载。但是,整个事情还是无法编译。
我想做的事合理吗?
解决方法
尝试以下操作(暂时关闭,可能有语法错误):
template < class Type >
Type ShiftLeft( Type lhs,Type rhs )
{
return LShift( lhs,rhs );
}
template <>
double ShiftLeft( double lhs,double rhs )
{
assert( \"ShiftLeft is not valid on floating types.\" && false );
return 0;
}
或者,您可以通过Boostenable_if
使用SFINAE。
但是有一种强烈的气味。未调用专业化(!)的代码很可能应该重构。某种程度上来说。
干杯,……