Мне нужна функция шаблона, которая принимает указатель на член, но я не хочу передавать ни тип класса, ни тип члена - PullRequest
1 голос
/ 09 ноября 2011

Итак, я ломал голову, пытаясь найти путь к чему-то.Я думал, что отправлю это здесь, чтобы видеть, есть ли у кого-нибудь какие-либо идеи.Рассмотрим следующее:

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>();
}

Я бы хотел, чтобы функция GetSortByMember возвращала указатель функции на соответствующее создание экземпляра SortByMember.Однако я не могу придумать способ объявить / определить GetSortByMember таким образом, чтобы пользователь не передавал также тип класса и тип члена.Это:

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

слишком многословно и требует от меня указать тип члена.Я уверен, что, вероятно, есть решение в библиотеках boost, но я бы предпочел не вводить эту зависимость в проект, над которым я работаю.

Я очень сомневаюсь, что есть решение, которое даст точноесинтаксис, который я использовал в псевдокоде, но, возможно, что-то можно сделать с шаблонными классами или макросами?

Подпись SortByMember ожидается классом, который будет использовать указатель функции, поэтому его нельзя изменить.

Ответы [ 2 ]

0 голосов
/ 09 ноября 2011

Возможно, есть лучший способ сделать то, что вы хотите, но это работает с использованием макросов и специфического для GCC typeof (). Я не уверен, но в новом стандарте 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;
}
0 голосов
/ 09 ноября 2011

Ваш пример не понятен, возможно, вам нужно вызвать полученную функцию с двумя аргументами?Если так, почему бы не использовать функцию получения и передать ее, например:

#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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...