Информация об изменениях

Сообщение Re[4]: Восстановил (msvc only) от 28.09.2018 13:02

Изменено 28.09.2018 13:15 rg45

Re[4]: Восстановил (msvc only)
Здравствуйте, _NN_, Вы писали:


_NN>Где код ?

_NN>Может получиться что-нибудь придумать.

Вот, восстановил, все-таки. Это работает на mcvc, но не работает на gcc. Ключевой момент в том, что по стандарту хелперная функция не должна в этом случае вноситься в область видимости пространства имен. Но вот на msvc вносится. Э-х-х! сколько клевых фишек можно было бы сделать, будь это стандартым поведением! Синтаксическим сахаром на этор раз не стал особо заморачиваться, ибо все равно не портабельно:

template<typename TagT, typename MemPtrT, MemPtrT memPtr>
struct PrivateMemerAccessEnabler
{
   using PointerToMemberType = MemPtrT;
   static constexpr const PointerToMemberType pointerToMember = memPtr;
   friend PrivateMemerAccessEnabler privateMemerAccessEnablerAux(TagT&&);
};

template <typename TagT>
using PrivateMemberAccess = decltype(privateMemerAccessEnablerAux(std::declval<TagT>()));

#define ENABLE_PRIVATE_MEMBER_ACCESS(TagT, memPtr)    struct TagT;    template struct PrivateMemerAccessEnabler<A_value, decltype(memPtr), memPtr>;

struct A
{
public:

   int GetValue() const { return value; }

private:
   int value = -1;
};

ENABLE_PRIVATE_MEMBER_ACCESS(A_value, &A::value)

int main()
{
   const auto& memPtr = PrivateMemberAccess<A_value>::pointerToMember;

   A a;
   std::cout << a.GetValue() << std::endl;
   a.*memPtr = 42;
   std::cout << a.GetValue() << std::endl;
}
Re[4]: Восстановил (msvc only)
Здравствуйте, _NN_, Вы писали:


_NN>Где код ?

_NN>Может получиться что-нибудь придумать.

Вот, восстановил, все-таки. Это работает на mcvc, но не работает на gcc. Ключевой момент в том, что по стандарту хелперная функция не должна в этом случае вноситься в область видимости пространства имен. Но вот на msvc вносится. Э-х-х! сколько клевых фишек можно было бы сделать, будь это стандартым поведением! Синтаксическим сахаром на этор раз не стал особо заморачиваться, ибо все равно не портабельно:

#include <iostream>
#include <utility>

template<typename TagT, typename MemPtrT, MemPtrT memPtr>
struct PrivateMemerAccessEnabler
{
   using PointerToMemberType = MemPtrT;
   static constexpr const PointerToMemberType pointerToMember = memPtr;
   friend PrivateMemerAccessEnabler privateMemerAccessEnablerAux(TagT&&);
};

template <typename TagT>
using PrivateMemberAccess = decltype(privateMemerAccessEnablerAux(std::declval<TagT>()));

#define ENABLE_PRIVATE_MEMBER_ACCESS(TagT, memPtr)    struct TagT;    template struct PrivateMemerAccessEnabler<A_value, decltype(memPtr), memPtr>;

struct A
{
public:

   int GetValue() const { return value; }

private:
   int value = -1;
};

ENABLE_PRIVATE_MEMBER_ACCESS(A_value, &A::value)

int main()
{
   const auto& memPtr = PrivateMemberAccess<A_value>::pointerToMember;

   A a;
   std::cout << a.GetValue() << std::endl;
   a.*memPtr = 42;
   std::cout << a.GetValue() << std::endl;
}