Должно ли это работать? - PullRequest
2 голосов
/ 13 мая 2010

Я пытаюсь специализировать метафункцию на типе, у которого указатель функции является одним из его параметров. Код компилируется просто отлично, но он просто не будет соответствовать типу.

#include <iostream>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/identity.hpp>

template < typename CONT, typename NAME, typename TYPE, TYPE (CONT::*getter)() const, void (CONT::*setter)(TYPE const&) >
struct metafield_fun {};

struct test_field {};

struct test
{
  int testing() const { return 5; }
  void testing(int const&) {}
};

template < typename T >
struct field_writable : boost::mpl::identity<T> {};

template < typename CONT, typename NAME, typename TYPE, TYPE (CONT::*getter)() const >
struct field_writable< metafield_fun<CONT,NAME,TYPE,getter,0> > : boost::mpl::false_
{};

typedef metafield_fun<test, test_field, int, &test::testing, 0> unwritable;

int main()
{
  std::cout << typeid(field_writable<unwritable>::type).name() << std::endl;

  std::cin.get();
}

Выходные данные всегда передаются по типу, а не по имени bool.

1 Ответ

3 голосов
/ 14 мая 2010

В качестве рабочей альтернативы без проблем конвертации, упомянутых в комментариях:

struct rw_tag {};
struct ro_tag {};

template<typename CONT, typename NAME, typename TYPE,
         TYPE (CONT::*getter)() const, void (CONT::*setter)(TYPE const&)>
struct metafield_fun_rw : rw_tag {};

template<typename CONT, typename NAME, typename TYPE,
         TYPE (CONT::*getter)() const>
struct metafield_fun_ro : ro_tag {};

template<class T> struct field_writable 
  : boost::mpl::bool_< boost::is_base_of<rw_tag, T>::value >
// or just derive directly from: boost::is_base_of<rw_tag, T>::value
{};

typedef metafield_fun_ro<test, test_field, int, &test::testing> unwritable;

В качестве альтернативы metafield_fun может также typedef readwrite- / readonly-tags в зависимости от своих аргументов и field_writable выводится условно, скажем, с использованием boost::mpl::if_.

...