在 constexpr lambda 的默认模板参数上使用 enable_if

问题描述

我正在尝试编写一个始终返回 -1 的通用函数。我希望模板参数列表认为 int。我正在尝试使用 std::enable_ifstd::enable_if_t 来测试 T 类型是否为使用 std::is_arithmeticstd::is_arithmetic_v 的有效算术类型。我有语法问题无法正确编译。这是我的 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>();
}

解决方法

对 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,int> = 0>
static constexpr T negative_one() { 
    return static_cast<T>(-1); 
};