基于模板成员存在的 C++ 成员重载
C++ member overloads based on existence of template member
我从一些 SFINAE 开始,但我无法完全掌握我想使用它的一些情况。
例如,如果我有一个基于 class 的模板,它应该根据模板参数具有不同的函数实现,即
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();
我的编译器抛出
error: ‘class cARD’ has no member named ‘member’
在 decltype 行上(即使未定义回退函数)。这似乎与答案 相矛盾,那么定义尾随 return 类型的正确方法是什么?
此外,该函数显然不能重载。有没有简单的方法来定义回退函数?
你有一个硬错误,因为你的方法不是模板,将其更改为:
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>{});
}
};
我从一些 SFINAE 开始,但我无法完全掌握我想使用它的一些情况。
例如,如果我有一个基于 class 的模板,它应该根据模板参数具有不同的函数实现,即
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();
我的编译器抛出
error: ‘class cARD’ has no member named ‘member’
在 decltype 行上(即使未定义回退函数)。这似乎与答案
此外,该函数显然不能重载。有没有简单的方法来定义回退函数?
你有一个硬错误,因为你的方法不是模板,将其更改为:
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>{});
}
};