gpt4 book ai didi

c++ - 处理重构、模板 SFINAE 测试和 lambda

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:03:50 25 4
gpt4 key购买 nike

以下(学术构建的,非工作的)代码有两个“问题”,我知道如何以丑陋的方式解决。我想要一个漂亮的。

#include <type_traits>

template<class T> struct Integer {
Integer(T t) { static_assert(std::is_integral_v<T>, "Must be int"); }
};

template<class T> struct Floating {
Floating(T t) { static_assert(std::is_floating_point_v<T>, "Must be flating point"); }
};

template<class T> void brol(T t)
{
Integer i(t); //these two cannot work together
Floating f(t);

template<class U> auto stuff = [] (U& u) -> void //invalid syntax : no template on bloc scope
{ u *= 2; }

if(std::is_integral_v<T>)
stuff(i);
else
stuff(f);
}

int main()
{
brol(2);
brol(2.0);
}
  1. 显然,由于 static_asserts,我不能在函数 brol() 中构建一个 Integer 和一个 Floating。这个问题可以通过 SFINAE 测试轻松解决,可以很好地使用 std::enable_if_v 或一些 ... -> decltype( ... ) 技巧。同样的,我也可以改进函数体的结尾,避免if/else block
  2. lambda stuff() 不能是模板(因为编译器声明它不能)。我* 可以 * 使其独立并将其隐藏在子命名空间中,但效果不是很好。

但是,我不能简单地使用 std::enable_if 进行 SFINAE 测试,因为原型(prototype)只会与其默认模板参数不同,这是非法的(参见文档, 中的注释部分>std::enable_if).

另一方面,我不知道如何很好地解决ussie 2...

最佳答案

在我看来,std::conditional 应该可以解决您所有的问题

template <typename T>
void brol (T t)
{
using U = std::conditional_t<std::is_integral_v<T>, Integer<T>, Floating<T>>;

U u{t};

auto stuff = [] (U & u) -> void { u *= 2; };

stuff(u);
}

无论如何,lambda 的问题也可以用通用的 lambda 来解决(如 rustyx 所指出的)

   auto stuff = [] (auto & u) -> void { u *= 2; };

关于最后的 if,在 C++17 中(你使用的是 std::is_integral_v,所以你使用的是 C++17)你也可以使用 if constexpr 在类似的情况下

if constexpr (std::is_integral_v<T>)
stuff(i);
else
stuff(f);

但仍然存在您必须定义 if 的问题。

关于c++ - 处理重构、模板 SFINAE 测试和 lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54481589/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com