模板功能的`boost :: hana`自省 [英] `boost::hana` introspection for templated function

查看:282
本文介绍了模板功能的`boost :: hana`自省的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想确定类型是否定义了带有模板参数的成员函数,但模板参数受SFINAE约束.

I would like to find out if a type defines a member function with a template argument but the template argument is constrained with SFINAE.

示例我有一个类型为A的单个函数foo

Example I have a type A with a single function foo

struct A{
   template<typename T>
   std::enable_if<Condition<T>,ReturnType> foo(T t){ ... }
};

Condition是某种情况,例如std::is_pos_v

现在我正在使用boost::hana::is_valid来确定类型是否具有像foo()foo(int)这样的成员函数,但是当使用模板参数时,我会迷路.

Right now I'm using boost::hana::is_valid to figure out if a type has a member function like foo() or foo(int) but when with template argument I'm lost.

我想写这样的东西

auto has_foo = hana::is_valid([](auto t) -> delctype(hana::traits::declval(t).foo(???)){});
has_foo(hana::type_c<A>); // <-- I want this to return true

问题是我应该代替???放什么?

The question is what should I put instead of ??? ?

编译器可能不可能证明"类型A满足:对于每个满足Condition的类型T,都有成员函数A::foo(T)"

It is probably impossible for the compiler to "prove" that a type A satisfy: "For every type T which satisfy Condition there is a member function A::foo(T)"

因此,为了使编译器更容易,我很乐意至少证明"对于类型A的成立:存在类型T使得存在成员函数A::foo(T)"

So to make it easier for the compiler, I would be happy to at least "prove" that for a type A holds: "There is a type T such that there is a member function A::foo(T)"

不幸的是,在我的示例中,这仍然很难,因为这需要证明存在满足Condition的类型.

Unfortunately, this is still hard in my example because this would require proving that there is a type which satisfy Condition.

因此,出于内省的目的,是否有可能忽略SFIANE?然后我可以选择一个任意类型并测试例如A::foo(int).

Thus isn't it possible for the purpose of introspection to ignore SFIANE? Then I could pick an arbitrary type and test existence of e.g. A::foo(int).

推荐答案

如上所述,除了编写编译器插件并亲自执行AST之外,没有提供用于这种自省的工具.

As stated, there is no facility provided for this kind of introspection short of writing a compiler plugin and walking the AST yourself.

如果您提供了具体的T做出完整而有效的表达式.

You can certainly use hana::is_valid if you provide a concrete T to make a complete and valid expression.

我提供了另一个示例,该示例允许提供概念",并假设某种设施可以为您输入的任何概念"提供具体的"T".这还是可以达到的.

I provided an additional example that allows providing a "concept" assuming some kind of facility for providing a concrete T for whatever "concept" you put in. This is a bit of a reach though.

#include <boost/hana.hpp>
#include <type_traits>
#include <utility>

namespace hana = boost::hana;
using hana::Sequence;


struct A {
    template <typename T>
    std::enable_if_t<Sequence<T>::value, void> foo(T) { }
};

struct B {
    template <typename T>
    void bar(T) { }
};


template <typename T>
auto has_foo_1 = hana::is_valid([](auto&& a)
    -> decltype(std::forward<decltype(a)>(a).foo(std::declval<T>())) { });


template <template <typename, typename> typename Concept>
auto declval_concept_impl = int{};

template <>
auto declval_concept_impl<Sequence> = hana::tuple<>{};

template <template <typename, typename> typename Concept>
using declval_concept = std::add_rvalue_reference_t<decltype(declval_concept_impl<Concept>)>;

template <template <typename, typename> typename Concept>
auto has_foo_2 = hana::is_valid([](auto&& a)
    -> decltype(std::forward<decltype(a)>(a).foo(declval_concept<Concept>{})) { });

int main() {
    A a;
    B b;

    static_assert(    has_foo_1<hana::tuple<>>(a));
    static_assert(not has_foo_1<hana::tuple<>>(b));
    static_assert(    has_foo_2<Sequence>(a));
    static_assert(not has_foo_2<Sequence>(b));
}

这篇关于模板功能的`boost :: hana`自省的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆