![](/img/trans.png)
[英]Can C++11 deduce class type and member type from pointer-to-member template parameter
[英]Is there anyway in C++11 to get member pointer type within a template?
我知道这在C ++ 03中是不可能的,但是我希望有一些新的巫术允许我这样做。 见下文:
template <class T>
struct Binder
{
template<typename FT, FT T::*PtrTomember>
void AddMatch();
};
struct TestType
{
int i;
};
int main(int argc, char** argv)
{
Binder<TestType> b;
b.AddMatch<int,&TestType::i>(); //I have to do this now
b.AddMatch<&TestType::i>(); //I'd like to be able to do this (i.e. infer field type)
}
在C ++ 11中有没有办法做到这一点? decltype会有帮助吗?
**更新:使用Vlad的例子我认为这样的事情会起作用(警告:我没有编译,因为我正在构建具有decltype支持的编译器)
template <class T>
struct Binder
{
template<typename MP, FT ft = decltype(MP)>
void AddMatch()
{
//static_assert to make sure MP is a member pointer of T
}
};
struct TestType
{
int i;
};
int main()
{
Binder<TestType> b;
b.AddMatch<&TestType::i>();
}
这会有用吗?
你要做的事情是不能做的,也就是说,你不能使用成员指针作为常量表达式,除非你有一个类型。 也就是说,必须提供非类型模板参数的类型,换句话说,模板参数没有类型推断。
这个怎么样(作为c ++ 03中的一个踢球者):
#include <iostream>
#include <typeinfo>
template< typename T > struct ExtractMemberTypeHelper;
template< typename R, typename T >
struct ExtractMemberTypeHelper< R(T::*) >
{
typedef R Type;
typedef T ParentType;
};
template< typename T >
struct ExtractMemberType : public ExtractMemberTypeHelper< T > {};
struct foo
{
int bar;
template< typename T >
void func( const T& a_Arg )
{
std::cout << typeid( typename ExtractMemberType< T >::Type ).name( ) << " " << typeid( typename ExtractMemberType< T >::ParentType ).name( ) << std::endl;
}
};
int main()
{
foo inst;
inst.func( &foo::bar );
}
您可以让“T”提供此信息。
template <class ...T>
struct BoundTypes { };
template <class U, class T>
struct BinderDecls {
void AddMatch();
};
template <class U, class T, class ...Ts>
struct BinderDecls<U, BoundTypes<T, Ts...>>
:BinderDecls<U, BoundTypes<Ts...>>
{
using BinderDecls<U, BoundTypes<Ts...>>::AddMatch;
template<T U::*PtrTomember>
void AddMatch();
};
template <class T>
struct Binder : BinderDecls<T, typename T::bound_types>
{ }
然后变得容易
struct TestType {
typedef BoundTypes<int, float> bound_types;
int i;
float j;
};
int main(int argc, char** argv)
{
Binder<TestType> b;
b.AddMatch<&TestType::i>();
b.AddMatch<&TestType::j>();
}
或者,您可以使用友元函数定义
template <class ...T>
struct BoundTypes { };
template <class U, class T>
struct BinderDecls {
template<T U::*ptr>
friend void addMatch(BinderDecl &u) {
// ...
}
};
template <class U, class ...Ts>
struct BinderDecls<U, BoundTypes<Ts...>> : BinderDecls<U, Ts>...
{ };
template<typename = void>
void addMatch() = delete;
template <class T>
struct Binder : BinderDecls<T, typename T::bound_types>
{ }
然后你就可以写了
struct TestType {
typedef BoundTypes<int, float> bound_types;
int i;
float j;
};
int main(int argc, char** argv)
{
Binder<TestType> b;
addMatch<&TestType::i>(b);
addMatch<&TestType::j>(b);
}
template <class T>
struct Binder
{
template<typename FT>
void AddMatch();
};
struct TestType
{
int i;
};
int main()
{
Binder<TestType> b;
b.AddMatch<decltype(&TestType::i)>();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.