模板功能的`boost :: hana`自省 [英] `boost::hana` introspection for templated function
问题描述
我想确定类型是否定义了带有模板参数的成员函数,但模板参数受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屋!