gpt4 book ai didi

c++ - Boost.花 : How to check if function has specialisation for a certain type?

转载 作者:行者123 更新时间:2023-11-30 00:47:15 26 4
gpt4 key购买 nike

我有一个模板函数,默认情况下没有定义,但它由某些类型特化:

template <typename T>
auto foo(bar &, const T &) -> void;

template <>
auto foo<std::string>(bar &, const std::string &) -> void {}

我如何编写一个 constexpr 函数来告诉我类型 T 是否具有上述函数的特化?

我的最大努力:

namespace detail {

auto has_foo(hana::is_valid([](auto &b, const auto &t) -> decltype(foo(b, t)) {}));

} // namespace detail

template <typename T>
constexpr auto has_foo() -> bool
{
using hana::type_c;

return detail::has_foo(type_c<bar>, type_c<T>);
}

static_assert(has_foo<std::string>());

但是,这个静态断言会触发,如果我做对了,我希望它不会触发。

最佳答案

这里的问题是你传递了 hana::type s 到需要实际对象的函数。当你写 detail::has_foo(type_c<bar>, type_c<T>) , Hana 通过 hana::type_c原样 detail::has_foo .但是因为 foo不能用 hana::type 调用s,它失败了。相反,您有两个选择。第一个选项是继续通过 hana::type s 至 detail::has_foo , 但要使用 declval 里面 has_foo (请注意,我已将适当的引用限定符添加到 barT ):

#include <boost/hana.hpp>
#include <string>
namespace hana = boost::hana;


struct bar { };

template <typename T>
auto foo(bar&, T const&) -> void;

template <>
auto foo<std::string>(bar&, std::string const&) -> void { }

namespace detail {
auto has_foo = hana::is_valid([](auto b, auto t) -> decltype(
foo(hana::traits::declval(b), hana::traits::declval(t))
) { });
}

template <typename T>
constexpr auto has_foo() -> bool {
return detail::has_foo(hana::type_c<bar&>, hana::type_c<T const&>);
}

static_assert(has_foo<std::string>(), "");

另一种选择是放弃使用 hana::type完全并将实际对象传递给detail::has_foo :

namespace detail {
auto has_foo = hana::is_valid([](auto& b, auto const& t) -> decltype(foo(b, t)) { });
}

template <typename T>
constexpr auto has_foo() -> decltype(
detail::has_foo(std::declval<bar&>(), std::declval<T const&>())
) { return {}; }

在这里,我使用 std::declval就好像我有正确类型的对象一样,然后我调用 detail::has_foo与那些“对象”。您选择哪个主要是偏好问题。此外,根据您的用例,当您调用 has_foo 时,实际对象可能可用。 .如果是这种情况,您可以重构为

namespace detail {
auto has_foo = hana::is_valid([](auto& b, auto const& t) -> decltype(foo(b, t)) { });
}

template <typename T>
constexpr auto has_foo(bar& b, T const& t) -> decltype(detail::has_foo(b, t)) { return {}; }

C++17 将通过移除常量表达式中对 lambda 的禁令使我们的生活变得更加轻松,这将允许您编写

constexpr auto has_foo = hana::is_valid([](bar& b, auto const& t) -> decltype(foo(b, t)) { });

因此不再需要外部助手。

另请注意,您并未专门测试 foo 是否为拥有 T专长 ,但真的是foo(...)表达式格式正确。这在存在重载或 ADL 的情况下可能会略有不同,但对于大多数用例来说应该足够了。我不确定是否可以精确地检查一个函数是否专用于某种类型。

希望这对您有所帮助!

关于c++ - Boost.花 : How to check if function has specialisation for a certain type?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35419045/

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