CORBA / OMG C ++ 11 Language Mapping

В настоящее время я работаю над [OMG13] (см. Ниже) совместимым частичным фасадом C ++ 11 для адаптации устаревшего (C ++) ORB; «частичный» в смысле только серверной части, без DII, без OBV и т. д. — таким образом, только очень простые вещи.

[OMG13] имеет в 6.25.6 Реализация интерфейса на основе наследования

Реализация должна быть получена из сгенерированного базового класса основанный на
определение интерфейса OMG IDL. Сгенерированные базовые классы известны
как скелет классы
, и производные классы известны как
классы реализации. Каждая операция интерфейса имеет
соответствующая виртуальная функция-член, объявленная в классе скелета.

[акцент мой]

Это, если понимать буквально, подразумевает, что для интерфейса A, определенного в idl, A_impl должен быть потомком A_skel

class A_impl : /* whatever, likely public */  A_skel {
/**/
};

Но фрагменты, приведенные в 6.25.6 сказать иначе

// C++
class A_skel : public virtual CORBA::servant_traits<A>::base_type { ... };
// C++
class A_impl: public virtual CORBA::servant_traits<A>::base_type { ... };

Итак, согласно фрагментам, A_impl и A_skel — братья и сестры, происходящие от одного и того же предка.


Решать, что делать, нетривиально, потому что стандарт для первого, C ++ до C ++ 11, mapping [OMG12], имеет 5.40.3 Реализация интерфейса на основе наследования

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

так что это «может», а не «должен» для C ++, до C ++ 11, отображение и фрагменты, приведенные в, соответствуют этому «может»

class POA_A : public virtual PortableServer::ServantBase
{
/* [...] */
}

/* [...] */

class A_impl : public POA_A
{
/* [...] */
};

и это также то, для чего построена устаревшая инфраструктура ORB, с которой я работаю (кроме того, что она предлагает [OMG12] -совместимую реализацию на основе делегирования).


Итак, как связать _skel и _impl в моем маленьком фасаде ORB, совместимом с c ++ 11, чтобы быть [OMG13] -совместимым и ужесточающим impl-кодом против возможного рефакторинга этой части [OMG13]?

Можно, например, рассмотрите возможность получения _impls из класса мультиплексирования наследования в стиле CRTP:

struct Snippet_Reading{};
struct Prose_Reading{};

namespace mock {

class IA{};

// impl specific, not important here
template<class Ifc>
struct LoremIpsum {};template<class Ifc>
class POA_Delegator {
// impl specific, not important here
};

namespace CORBA {
template<class Ifc>
struct servant_traits {
/// @TODO meditate how to implement that
typedef LoremIpsum<Ifc> base_type;
};
}
}

namespace detail {
using namespace mock;

template<typename Reading, class Ifc>
class Base {};

template<class Ifc>
class Base<Prose_Reading, Ifc> : public virtual POA_Delegator<Ifc> {};

template<class Ifc>
class Base<Snippet_Reading, Ifc> : public virtual CORBA::servant_traits<Ifc>::base_type {};
}

#if defined(PROSE_READING)
template <class Ifc>
using Base = detail::Base<Prose_Reading, Ifc>;
#elif  defined(SNIPPET_READING)
template <class Ifc>
using Base = detail::Base<Snippet_Reading, Ifc>;
#else
#error Oh My Goodness! Don't know how to interpret OMG's IDL to C++11 Mapping!
#endifclass IA_impl : public virtual Base<mock::IA> {};int main() {}

но это не совсем соответствует стандартному интерфейсу разработчика.

Рекомендации

[OMG12] OMG C ++ Language Mapping. OMG, 2012. http://www.omg.org/spec/CPP/1.3

[OMG13] OMG. C ++ 11 Language Mapping. OMG, 2013. http://www.omg.org/spec/CPP11/

0

Решение

CORBA :: servant_traits :: base_type должен преобразовываться в A_skel во время компиляции. Пользователь на самом деле не видит A_skel, это просто деталь реализации. Пользователь определил A_impl, а не только полученный из свойства CORBA :: servant_traits :: base_type.

В 6.26.6, как вы указали, есть ошибка. Классы скелета должны происходить друг от друга, а не от черт, поэтому должно быть так, как показано ниже, также отсутствует C_skel.

// C++
class A_skel : public virtual PortableServer::ServantBase {};
class B_skel : public virtual A_skel {};
class C_skel : public virtual A_skel {};
class D_skel : public virtual B_skel, public virtual C_skel {};

Для чернового проекта V1.1 см. http://osportal.remedy.nl. Мы также можем помочь с вашей задачей, не стесняйтесь связаться со мной напрямую.

Не могли бы вы сообщить об официальной проблеме в OMG для примера в 6.26.2, чтобы мы могли решить ее в версии спецификации V1.2?

1

Другие решения

В ответ на ответ Джонни Виллемсена:

Хорошо, давайте свяжем кусочки вместе:

Стандартные требования

class A_impl: public virtual CORBA::servant_traits<A>::base_type { ... };

и если это

CORBA :: servant_traits :: base_type должен преобразовываться в A_skel во время компиляции.

будет держаться для A_skel, определенного таким образом

class A_skel : public virtual PortableServer::ServantBase {};

тогда должна быть специализация для template<T>struct CORBA::servant_traitsИтак, я так понимаю, стандарт подразумевает такие зависимости:

class A {
public:
virtual long foo() = 0;
};

namespace mock {

namespace CORBA {
template<class Ifc>
struct servant_traits { /* ? */};
}

namespace PortableServer {
class ServantBase { /* ... */};
}
}

using namespace mock;

class A_skel : public virtual PortableServer::ServantBase {
virtual long foo() = 0;
};

namespace mock {
namespace CORBA {
template<>
struct servant_traits<A> {
typedef A_skel base_type;
// ...
};
}
}

class A_impl : public virtual CORBA::servant_traits<A>::base_type {
public:
virtual long foo() {
return 42;
}
};

int main() {}

Я правильно понял?

0

По вопросам рекламы [email protected]