成员函数指针的模板参数扣除 [英] Template argument deduction for member function pointers

查看:91
本文介绍了成员函数指针的模板参数扣除的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

已知模板参数可以是成员函数的指针。

It is known that template arguments can be pointers to member functions.

所以我可以写:

struct Bar
{
    int fun(float x);
};

template <int (Bar::*FUN)(float)>
struct Foo
{ /*...*/ };

typedef Foo<&Bar::fun> FooBar;

但是如果我想要 Bar 类型本身作为模板参数:

But what if I want the the Bar type itself to be a template argument:

template <typename B, int (B::*FUN)(float)>
struct Foo
{ /*...*/ };

typedef Foo<Bar, &Bar::fun> FooBar;

现在,当我使用它,我必须写 Bar 两次!

Now, when I use it, I have to write Bar twice!

我的问题是:是否有办法强制编译器自动推导类类型?

My question is: Is there a way to force the compiler to deduce the class type automatically?

目标是让这只是工作:

typedef Foo<&Bar::fun> FooBar;
typedef Foo<&Moo::fun> FooMoo;


推荐答案

你可能应该写类名。但是,如果你真的想避免,你可以使用宏的邪恶魔法。简单版本更危险:

You probably should just write the class name in there. However, if you really want to avoid that you can use the evil magic of macros. The simple version is more dangerous:

#define TT(X) decltype(X), X

template<typename T,T t>
struct Foo
{ /* ... */ };

struct Bar {
    int fun(float) {}
};

int main() {
    Foo<TT(&Bar::fun)> f;
}

这将接受任何类型的非类型模板参数,难以理解的错误,如果 Foo 实现只适用于指针成员。

This will accept any kind of non-type template parameter, and you may encounter hard-to-understand errors if the Foo implementation only works with pointers-to-member.

有点更安全,你需要一个元功能,告诉你类名:

To make it a bit safer you need a metafunction that tells you the class name:

template<typename T> struct member_ptr_traits;

template<typename Class,typename Ret,typename... Args>
struct member_ptr_traits<Ret (Class::*)(Args...)>
{
    typedef Class class_type;
    typedef Ret return_type;
};

#define TT(X) member_ptr_traits<decltype(X)>::class_type , X

template<typename T,int (T::*FUN)(float)>
struct Foo
{ /* ... */ };

struct Bar {
    int fun(float) {}
};

int main() {
    Foo<TT(&Bar::fun)> f;
}

这两个都使用C ++ 11,所以他们不能使用旧编译器。这个简单的版本可以重写为使用旧的 typeof 或类似的编译器扩展。重写更安全的版本需要模拟可变参数模板。

Also both of these use C++11 so they won't work with old compilers. This simple version can be rewritten to use the old typeof or similar compiler extensions. Rewriting the safer version requires simulating variadic templates.

这篇关于成员函数指针的模板参数扣除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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