我目前正在连接一个应用程序,该应用程序具有多个用于单一目的的实现。在运行时检查是否可以使用适当的实现或是否使用回退。
为此,我希望所有实现都实现一个静态函数 static bool is_available()
。
由于静态函数不能在底层基类中抽象化,是否有一些预处理器魔术可以让我在子类中未静态实现该方法时输出错误消息?
最佳答案
与user9400869's answer 一样,您可以使用 SFINAE 定义特征在编译时检查类的可用性:
#include <type_traits>
template<class LIB, class = void>
struct is_available
: std::false_type
{};
template<class LIB>
struct is_available<LIB, std::enable_if_t<std::is_invocable_r<bool, decltype(LIB::is_available)>::value>>
: std::integral_constant<bool, LIB::is_available()>
{};
template<class LIB>
constexpr bool is_available_v = is_available<LIB>::value;
这意味着库的 C++17 和 constexpr
函数 is_available
:
#include <iostream>
struct A {};
struct B { static constexpr bool is_available() { return false; } };
struct C { static constexpr bool is_available() { return true; } };
int main()
{
std::cout << is_available_v<A> // 0
<< is_available_v<B> // 0
<< is_available_v<C> // 1 :)
<< '\n';
}
如果 C++17 不是一个选项,您可以实现 std::is_invocable_r
仅使用 C++14 功能。
如果 constexpr
静态成员函数不是您的库类的选项,则您不能依赖 std::true_type
和 std::false_type
并且必须使用运行时结果收集:
#include <type_traits>
template<class LIB, class = void>
struct is_available
{
static bool value() { return false; }
};
template<class LIB>
struct is_available<LIB, std::enable_if_t<std::is_invocable_r<bool, decltype(LIB::is_available)>::value>>
{
static bool value() { return LIB::is_available(); }
};
关于c++ - 在编译时检查静态函数是否在类中可用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54920801/