Возможно ли иметь переменную-член, которая сможет вычислять указатель на содержащий объект из указателя на себя (в его методе)?переменная класса класса C++, зная ее собственное смещение
Давай интерфейс внешнего вызова, завернутый в API, как это:
template <typename Class, MethodId Id, typename Signature>
class MethodProxy;
template <typename Class, MethodId Id, typename ReturnT, typename Arg1T>
class MethodProxy<Class, Id, ReturnT()(Arg1T) {
public:
ReturnT operator()(Class &invocant, Arg1T arg1);
};
и аналогична для других чисел аргументов от 0 до N. Для каждого класса на внешней стороне, один класс C++ объявляются с некоторыми и этот шаблон использует эти черты (и больше признаков для типов аргументов) для поиска и вызова внешнего метода. Это может быть использовано как:
Foo foo;
MethodProxy<Foo, barId, void()(int)> bar;
bar(foo, 5);
Теперь то, что я хотел бы сделать, это определить Foo
таким образом, что я могу назвать как:
Foo foo;
foo.bar(5);
, не повторяя подпись, несколько раз. (очевидно, создание статического члена и перенос вызова методом простым, правильным). Ну, в самом деле, что по-прежнему легко:
template <typename Class, MethodId Id, typename Signature>
class MethodMember;
template <typename Class, MethodId Id, typename ReturnT, typename Arg1T>
class MethodMember<Class, Id, ReturnT()(Arg1T) {
MethodProxy<Class, Id, Signature> method;
Class &owner;
public:
MethodMember(Class &owner) : owner(owner) {}
ReturnT operator()(Arg1T arg1) { return method(owner, arg1); }
};
Это однако означает, что объект будет в конечном итоге, содержащий большое количество копий указатель на себя. Поэтому я ищу способ сделать эти экземпляры способными вычислить указатель владельца от this
и некоторые дополнительные аргументы шаблона.
Я думал вдоль линий
template <typename Class, size_t Offset, ...>
class Member {
Class *owner() {
return reinterpret_cast<Class *>(
reinterpret_cast<char *>(this) - Offset);
}
...
};
class Foo {
Member<Foo, offsetof(Foo, member), ...> member;
...
};
но жалуется, что Foo является неполным типа в точке.
Да, я знаю, что offsetof
должен работать только для типов «POD», но на практике для любого не виртуального элемента, который это будет, работает. Аналогичным образом я попытался передать в этом аргументе указатель-to-the (-member) (используя фиктивный базовый класс), но это тоже не работает.
Обратите внимание, что если это сработало, оно также может быть использовано для реализации свойств, связанных с C#, передающих методы содержащего класс.
Я знаю, как использовать описанные выше методы обертки с boost.preprocessor, но списки аргументов должны быть указаны в странной форме. Я знаю, как писать макрос для создания общих оболочек с помощью шаблонов, но это, вероятно, даст плохую диагностику. Было бы также тривиально, если бы вызовы могли выглядеть как foo.bar()(5)
. Но я хотел бы знать, возможно ли умный трюк (плюс только такой умный трюк, вероятно, будет полезен и для свойств).
Примечание. Тип элемента не может быть фактически специализирован ни на указателе участника, ни на его смещении, поскольку тип должен быть известен до того, как это смещение может быть назначено. Это потому, что тип может повлиять на требуемое выравнивание (рассмотрим явную/парциальную специализацию).
Я читал, что в несколько раз, но до сих пор не понимаю, что вы хотите сделать, вы хотите родовое * свойство * класс, который знает о что ему принадлежит - если да, зачем ему нужно знать, что ему принадлежит? Я должен представить себе, что все необходимое свойство - это способность принимать значение и возвращать значение? – Nim
Я тоже этого не понимаю.Что ты пытаешься сделать? – mfontanini
@Nim: Да, мне нужен общий класс свойств, который знает, что ему принадлежит. Для свойства необходимо, если значение свойства должно быть * вычислено *. В моем случае, однако, функтор должен передать указатель владельцу на основной метод. –