【问题标题】:Using enable_if on a defaulted template argument for a constexpr lambda在 constexpr lambda 的默认模板参数上使用 enable_if
【发布时间】:2021-02-03 00:00:23
【问题描述】:

我正在尝试编写一个始终返回-1 的通用函数。我希望模板参数列表默认为int。我正在尝试使用std::enable_ifstd::enable_if_t 通过使用std::is_arithmeticstd::is_arithmetic_v 来测试T 类型是否是有效的算术类型。我遇到语法问题才能使其正确编译。这是我的 lambda 的样子:

template<typename T = int,
std::enable_if_t<std::is_arithmetic_v<T>> >
static constexpr T negative_one = [](){ 
    return static_cast<T>(-1); 
};

这是一个非常微不足道的函数和概念,但编译器想抱怨默认参数不在参数列表的末尾......它的正确定义应该是什么样子?

这就是我将如何使用它:

{
    int i = negative_one();
    float f = negative_one<float>();
}

【问题讨论】:

    标签: c++ templates lambda c++17 default-arguments


    【解决方案1】:

    对 sfinae 使用非类型可选模板参数。如果您想调用它/将其作为谓词传递,您的类型必须是 lambda 类型(而不是 T)。您可以通过自动类型推断来实现这一点。

    template<typename T = int, std::enable_if_t<std::is_arithmetic_v<T>, int> = 0>
    static constexpr auto negative_one = [](){ 
        return static_cast<T>(-1); 
    };
    

    另一种选择是使用函数而不是 lambda:

    
    template<typename T = int, std::enable_if_t<std::is_arithmetic_v<T>, int> = 0>
    static constexpr T negative_one() { 
        return static_cast<T>(-1); 
    };
    

    【讨论】:

    • 我很欣赏这两种情况,但我可能想将其作为可以使用 lambda 的谓词传入!但我不知道在声明定义的那个站点调用 lambda ......我也错过了 class = 部分。非常感谢!
    • 有一个问题,但当我使用 lambda 时,它抱怨 int i = negative_one; 缺少所需的模板参数。这样做的全部目的是让int 成为默认值,我不必告诉它是int,但对于其他类型,例如floatdoublecharbool它们必须被表达出来。
    • int i = negative_one&lt;&gt;();
    • 首选std::enable_if_f&lt;cond&lt;T&gt;, int&gt; = 0而不是typename = std::enable_if_f&lt;cond&lt;T&gt;&gt;,后者可以被劫持(negative_one&lt;SomeType, int&gt;)。
    • 使用 C++20 概念会变得更好godbolt.org/z/ETv3YW
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-16
    • 2016-10-06
    相关资源
    最近更新 更多