C++基于模板成员的存在进行成员重载

C++ member overloads based on existence of template member

本文关键字:成员 重载 存在 于模板 C++      更新时间:2023-10-16

我一直从一些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();

我的编译器抛出

错误:"类 cARD"没有名为"成员"的成员

在 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>{});
}
};