简体   繁体   English

我想要一个带有指向成员的指针的模板函数,但是我不想传递类类型或成员类型

[英]I want a template function that takes a pointer to member, but I don't want to have to pass the class type nor the member type

So I've been racking my brain trying to figure out a way to something. 因此,我一直在绞尽脑汁,想出办法。 I thought I'd post it here to see if anyone has any ideas. 我以为我会在这里贴一下,看看是否有人有任何想法。 Consider the following: 考虑以下:

template <typename S, typename T, T S::* pMember>
bool SortByMember(const S& L, const S& R)
{
    return L.*pMember < R.*pMember;
}

...

struct SomeStruct
{
    int SomeMember;
};

void SomeFunction(void)
{
    GetSortByMember<&SomeStruct::SomeMember>();
}

I would like the function, GetSortByMember, to return a function pointer to the corresponding instantiation of SortByMember. 我希望函数GetSortByMember返回一个函数指针,该指针指向SortByMember的相应实例。 However, I can't think of a way to declare/define GetSortByMember in a way that doesn't require the user to also pass the class type and the member type. 但是,我想不出一种不需要用户也传递类类型和成员类型的方式来声明/定义GetSortByMember的方法。 This: 这个:

GetSortByMember<SomeStruct, int, &SomeStruct::SomeMember>();

is overly verbose and requires me to state the member type. 过于冗长,需要我声明成员类型。 I'm sure there's probably a solution in the boost libraries, but I'd rather not introduce that dependency to the project I'm working on. 我确定boost库中可能有一个解决方案,但我不想将这种依赖关系引入到我正在从事的项目中。

I doubt highly that there's a solution that'll yield the exact syntax I used in the psudocode, but perhaps something can be done with template classes or macros? 我高度怀疑是否有一种解决方案能够产生我在psudocode中使用的确切语法,但是也许可以通过模板类或宏来完成某些工作?

The signature of SortByMember is expected by the class that will be using the function pointer, so it can't be changed. 使用函数指针的类需要使用SortByMember的签名,因此无法更改。

Your example is not clear, presumably, you need to call the resulting function with two arguments? 您的示例不清楚,想必您需要使用两个参数来调用结果函数吗? If so, why not use a getter function and pass that in, eg: 如果是这样,为什么不使用getter函数并将其传入,例如:

#include <iostream>

struct foo
{
  int bar;
  int getBar() const { return bar; }
};

template <typename S, typename U>
bool SortByMember(const S& L, const S& R, U f)
{
    return (L.*f)()< (R.*f)();
}

int main(void)
{
  foo a = {1};
  foo b = {2};

  std::cout << SortByMember(a, b, &foo::getBar) << std::endl;
}

There might be a nicer way to do what you want but this works using macros and the GCC specific typeof(). 可能有更好的方法来执行所需的操作,但这可以使用宏和特定于GCC的typeof()来工作。 I'm not sure but there might be a portable way to do typeof in the new C++ standard. 我不确定,但是在新的C ++标准中可能会有一种可移植的方式来进行typeof。

#include <iostream>

template <class P, P p>
class sort_by_member_t;

template <class S, class T, T S::*p>
class sort_by_member_t<T S::*, p> {
public:
    typedef bool (*fn_t)(S const&, S const&);

    static bool fn(S const& L, S const& R)
    {
        return L.*p < R.*p;
    }
};

#define SORT_BY_MEMBER(p) sort_by_member_t<typeof(p), p>::fn;

struct SomeStruct
{
    int SomeMember;
};


int main()
{
    bool (*fp)(SomeStruct const&, SomeStruct const&);
    fp = SORT_BY_MEMBER(&SomeStruct::SomeMember);
    SomeStruct const a = { 1 };
    SomeStruct const b = { 2 };
    std::cerr
        << (void*) fp << ' '
        << (*fp)(a, b) << ' '
        << (*fp)(b, a) << ' '
        << '\n';

    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM