gpt4 book ai didi

c++ - 为什么 `has_construct::value` 在 gcc (false) 和 clang (true) 上给出不同的值?

转载 作者:行者123 更新时间:2023-11-28 05:53:36 26 4
gpt4 key购买 nike

我正在尝试实现allocate_traits,然后我尝试了很多方法,最后让它在gcc(>= 5)下运行良好,下面是一个判断的类>allocate_traits::construct

template <typename ...>
using type_helper = void;

template <typename T, typename... Args>
struct has_construct_helper {
template <typename Alloc, typename = type_helper<
decltype(declval<Alloc &>().construct
(declval<T *>(), declval<Args>()...))
>> static constexpr true_type test(Alloc, int);

template <typename Alloc> static constexpr false_type test(Alloc, ...);
};

template <typename Alloc, typename T, typename... Args>
using has_construct =
decltype(has_construct_helper<T, Args...>::test(declval<Alloc>(), 0));

我用一个不包含 construct 的分配器对其进行了测试,并且它与 gcc (>= 5) 配合得很好,但是 clang (>= 3.7) 给我 true。此代码有效吗?

有一个完整的文件有同样的错误并且可能更简单: https://gist.github.com/anonymous/9a6125c4796d4c0227cb

最佳答案

问题出在您的 type_helper 别名模板上。对于如何处理未使用的可变参数模板参数,标准中曾经存在歧义。 Clang 决定不理会它们,因此您的 decltype 表达式实际上从未被检查过,因此 SFINAE 不会发生。

简单的解决方法是推迟到另一个特征,以便评估参数:

template <typename...> struct voider { using type = void; };
template <typename...Ts> using type_helper = typename voider<Ts...>::type;

这是您的代码的一个稍微简单的版本,它使用 SFINAE 的检测习惯用法。

template <typename...> struct voider { using type = void; };
template <typename...Ts> using void_t = typename voider<Ts...>::type;

template <typename Alloc, typename T, typename, typename... Args>
struct has_construct_helper : std::false_type{};

template <typename Alloc, typename T, typename... Args>
struct has_construct_helper<Alloc, T,
void_t<decltype(declval<Alloc &>().construct
(declval<T *>(), declval<Args>()...))>,
Args...> : std::true_type
{};

template <typename Alloc, typename T, typename... Args>
using has_construct = typename has_construct_helper<Alloc, T, void, Args...>::type;

template <typename Alloc, typename T, typename... Args>
void doConstruct(std::true_type, Alloc &a, T *p, Args&&... args)
{
a.construct(p, forward<Args>(args)...);
}

template <typename Alloc, typename T, typename... Args>
void doConstruct(std::false_type, Alloc &, T *p, Args&&... args)
{
::new (static_cast<void *>(p)) T(forward<Args>(args)...);
}


template <typename Alloc>
class allocator_traits {
public:
//...
template <typename T, typename... Args> static
void construct(Alloc &a, T *p, Args&&... args)
{
doConstruct(has_construct<Alloc,T,Args...>{}, a, p, forward<Args>(args)...);
}
//...
};

Live Demo

关于c++ - 为什么 `has_construct<Alloc, T, Args...>::value` 在 gcc (false) 和 clang (true) 上给出不同的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34676716/

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