我一直在使用一些SFINAE,但我无法处理一些我想用它的情况。
例如,如果我有一个基于模板的类,它应该根据模板参数具有不同的函数实现,即
template <typename T>
class cExampleClass
{
/// Function enabled when "cExampleClass::member" exists
auto overloadedFunction() -> decltype((std::declval<t>().member()),T::some_dependant_type())
{
// Do some stuff and use cExampleClass::member
}
/// Function enabled when "cExampleClass::member" does not exist
auto overloadedFunction() -> T::some_dependant_type()
{
// Do some different stuff
}
};
将函数称为
是理想的object.overloadedFunction();
我的编译器抛出
decltype行上的错误:'class cARD'没有名为'member'的成员
(即使未定义回退功能)。这似乎与答案here相矛盾,那么定义尾随返回类型的正确方法是什么?
此外,该功能显然不能超载。有没有简单的方法来定义回退函数?
答案 0 :(得分:1)
您有一个硬错误,因为您的方法不是模板,请将其更改为:
template <typename U>
class cExampleClass
{
/// Function enabled when "cExampleClass::member" exists
template <typename T = U>
auto overloadedFunction()
-> decltype((std::declval<T>().member()),T::some_dependant_type())
{
// Do some stuff and use cExampleClass::member
}
/// Function enabled when "cExampleClass::member" does not exist
template <typename T = U>
auto overloadedFunction() -> decltype(T::some_dependant_type())
{
// Do some different stuff
}
};
但是你有问题,因为这个方法对于符合这两个条件的类型都是不明确的。
添加标签以排序重载是可能的:
template <std::size_t I>
struct overload_tag : overload_tag<I - 1> {};
template <>
struct overload_tag<0> {};
然后
template <typename U>
class cExampleClass
{
private:
/// Function enabled when "cExampleClass::member" exists
/// Preferred function
template <typename T = U>
auto overloadedFunction(overload_tag<1>)
-> decltype((std::declval<T>().member()),T::some_dependant_type())
{
// Do some stuff and use cExampleClass::member
}
/// Function enabled when "cExampleClass::member" does not exist
template <typename T = U>
auto overloadedFunction(overload_tag<0>) -> decltype(T::some_dependant_type())
{
// Do some different stuff
}
public:
template <typename T = U>
auto overloadedFunction() -> decltype(overloadedFunction(overload_tag<1>{}))
{
return overloadedFunction(overload_tag<1>{});
}
};