gpt4 book ai didi

templates - C++11:模板参数中的 SFINAE,GCC 与 Clang

转载 作者:行者123 更新时间:2023-12-04 14:43:57 24 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





Is there a compiler bug exposed by my implementation of an is_complete type trait?

(1 个回答)


4年前关闭。




我想实现一个小的 trait-class 来确定一个类型是否已经重载 operator()正确,以便我可以查询这样的类型:

FunctorCheck<F, void(int, char)>::value

最初,我从 this question 得到了如何实现这一点的想法。 ,但在看到 Cppcon lecture on TMP 后,我突然意识到这个问题可以更优雅地解决。这就是我想出的,它可以在 Clang 3.5.0 上编译并完美运行:
template <typename ...>
using void_t = void;

template <typename Functor, typename ... Args>
using FunctorReturn = decltype(declval<Functor>()(declval<Args>()...));

template <typename Functor, typename Signature, typename = void>
struct FunctorCheck: public std::false_type
{};

template <typename Functor, typename R, typename ... Args>
struct FunctorCheck<Functor, R(Args...),
void_t<FunctorReturn<Functor, Args ...>> // SFINAE can kick in here
> : public std::is_same<R, FunctorReturn<Functor, Args ...>>::type
{};

您可能已经注意到,我正在使用建议的 C++17 void_t在特化的模板参数中利用 SFINAE。当 FunctorReturn收到 Functor与参数列表不兼容的类型, void_t<FunctorReturn<Functor, Args ...>>格式错误,SFINAE 将启动,非专业版本将被实例化。如果前一个表达式是良构的, std::is_same比较返回类型以确定我们是否匹配。

在前面提到的讲座中,Walter Brown 提到这种技术从第一天开始就在 Clang 上起作用,而从第一天开始就没有在 GCC 上起作用,仅仅是因为他们在标准未能指定的某些东西上选择了不同的实现。但是,鉴于此版本是 更优雅 与我以前相比,有什么我可以做的事情可以在 GCC (>= 4.9) 上进行编译?

(另外,有没有人知道这在最新版本的 Visual Studio 上会如何表现?)

最佳答案

这是 CWG issue 1558 .未指定的部分是对别名模板中未使用参数的处理。在 GCC < 5.0 中,未使用的参数不会导致替换失败,因此 void_t fails to verify your functor call ,并尝试实例化类模板特化,这会导致硬错误。

GCC (< 5.0) 的解决方法是以下实现:

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

template <typename... Ts>
using void_t = typename voider<Ts...>::type;

DEMO

关于templates - C++11:模板参数中的 SFINAE,GCC 与 Clang,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28282398/

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