如果模板值可转换为布尔值,则在编译时禁用类方法

Disable class method at compile time if template value is castable to a bool

本文关键字:编译 类方法 可转换 布尔值 如果      更新时间:2023-10-16

如果类中包含的类型T可以转换为布尔值,我想禁用此类上的 no-arg 方法。

我一直在用enable_if尝试一些SFINAE的东西,但是我遇到了很多问题。我想要的可能吗?

template <typename T>
struct Watch {
    T t;
    // Enable if and only if bool(t) can be performed
    void stop() {
        // ...
    }
    void stop(int secondsFromNow) {
        // ...
    }
};
int main() {
    Watch<int> watch;
    watch.stop();
    watch.stop(5);
    Watch<string> watchStr;
    //watchStr.stop();
    watchStr.stop(2);
}

在阅读了许多关于使用 SFINAE 和模板隐藏内容的堆栈溢出帖子后,我一直无法让其他东西为我工作。

如果有人尝试调用Watch上不可转换为布尔值的元素,如何在不影响任何其他方法的情况下使在编译时调用stop()失败?

在这种情况下---当您想根据类的模板参数而不是函数本身的参数从重载解析中删除函数时---正确的习惯是将签名的实例化推迟到使用默认参数调用函数的点:

template <typename U = T, typename = std::enable_if_t<std::is_convertible_v<U, bool>>>
void stop();

在这里,在调用stopU被赋予值之前,不会尝试计算enable_if类型,因此 SFINAE 启动。

在某些情况下,您可能只是希望在不满足编译时条件时根本不声明函数。可以通过从包含或不包含相关函数的 CRTP 基类继承来实现此目的。