gpt4 book ai didi

c++ - 使用 enable_if 和 is_integral 来制作分布特征

转载 作者:行者123 更新时间:2023-11-28 07:03:26 29 4
gpt4 key购买 nike

我想根据给定的类型为 std::uniform_*_distribution 创建一个特征。例如:

distribution_traits<float>::type int_dist;

我尝试了以下方法,但没有一种编译通过,我也不知道为什么。

实现 1

std::enable_iftypedef 一起使用:

template <typename T>
struct distribution_traits {
using type = typename std::enable_if<std::is_integral<T>::value, std::uniform_int_distribution<T>>::type;
using type = typename std::enable_if<std::is_floating_point<T>::value, std::uniform_real_distribution<T>>::type;
};

Clang 3.4 提示:

dist_traits.cpp:7:9: error: redefinition of 'type'
using type = typename std::enable_if<std::is_floating_point<T>::value, std::uniform_real_distribution<T>>::type;
^
dist_traits.cpp:6:9: note: previous definition is here
using type = typename std::enable_if<std::is_integral<T>::value, std::uniform_int_distribution<T>>::type;
^
dist_traits.cpp:6:40: error: no type named 'type' in 'std::enable_if<false, std::uniform_int_distribution<float> >'; 'enable_if' cannot be used to
disable this declaration
using type = typename std::enable_if<std::is_integral<T>::value, std::uniform_int_distribution<T>>::type;
^~~~~~~~~~~~~~~~~~~~~~~~~~
dist_traits.cpp:28:3: note: in instantiation of template class 'distribution_traits<float>' requested here
distribution_traits<float>::type int_dist;
^
2 errors generated.

实现 2

使用enable_if作为类模板参数:

template <typename T, typename distribution_t = void>
struct distribution_traits;

template <typename T>
struct distribution_traits<
T, typename std::enable_if<std::is_integral<T>::value,
std::uniform_int_distribution<T> >::type > {
using type = std::uniform_int_distribution<T>;
};

template <typename T>
struct distribution_traits<
T, typename std::enable_if<std::is_floating_point<T>::value,
std::uniform_real_distribution<T> >::type > {
using type = std::uniform_real_distribution<T>;
};

Clang 提示

dist_traits.cpp:28:3: error: implicit instantiation of undefined template 'distribution_traits<float, void>'
distribution_traits<float>::type int_dist;
^

两种方式都无法被MSVC++ 12.0编译,报错信息也类似。

谁能解释一下我在 SFINAE 上做错了什么?谢谢!


对于那些对解决方案感到好奇的人,这里是编译的那个:

template <typename T>
auto dist() -> typename std::enable_if<std::is_integral<T>::value, std::uniform_int_distribution<T>>::type;

template <typename T>
auto dist() -> typename std::enable_if<std::is_floating_point<T>::value, std::uniform_real_distribution<T>>::type;

template <typename T>
struct distribution_traits {
using type = decltype(dist<T>());
};

顺便说一句,如果将 dist 函数放入 distribution_traits 中,编译将失败并出现错误:函数仅在返回类型上不同,无法重载。 :(

最佳答案

SFINAE 可用于在替换模板参数期间丢弃函数模板和类模板特化的重载。

它不能像您尝试的那样与类型/模板别名一起使用。

关于您的工作代码 - 放置 dist类内部不起作用,因为您试图调用 dist里面decltype没有对象。制作dist静态的,它会工作:

template <typename T>
struct distribution_traits {
template <typename U>
static auto dist() -> typename std::enable_if<std::is_integral<U>::value, std::uniform_int_distribution<U>>::type;

template <typename U>
static auto dist() -> typename std::enable_if<std::is_floating_point<U>::value, std::uniform_real_distribution<U>>::type;

using type = decltype(dist<T>());
};

要使实现 2 起作用,您需要省略 enable_if 的第二个参数:

模板结构分布特征;

template <typename T>
struct distribution_traits<
T, typename std::enable_if<std::is_integral<T>::value>::type> {
using type = std::uniform_int_distribution<T>;
};

否则你定义的特化是distribution_traits<T, uniform_int_distribution<T>>这与 distribution_traits<float> 这样的实例不匹配因为第二个参数默认为void .

关于c++ - 使用 enable_if 和 is_integral 来制作分布特征,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22118050/

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