разрешение оператора С ++ новой неопределенности (как его форсировать)? - PullRequest
0 голосов
/ 20 ноября 2011

Мой код (еще не выпущен, в файле iaca.hh) находится на pastebin: новый конфликт Basile Iaca C ++ Я использую GCC 4.6 на Debian / Linux / Sid AMD64 с C ++ 11диалект.

g++  -std=c++0x -Wall -Wextra -g -O -flto -I/usr/local/include -o iaca.hh.gch iaca.hh 
iaca.hh:631:2: warning: #warning should implement the methods [-Wcpp]
iaca.hh: In static member function 'static IaDictionnaryItem* IaDictionnaryItem::make()':
iaca.hh:964:46: error: request for member 'operator new' is ambiguous
/usr/local/include/gc/gc_cpp.h:304:14: error: candidates are: static void* gc::operator new(size_t, void*)
/usr/local/include/gc/gc_cpp.h:296:14: error:                 static void* gc::operator new(size_t, GCPlacement)
/usr/local/include/gc/gc_cpp.h:293:14: error:                 static void* gc::operator new(size_t)
iaca.hh:675:7: error:                 static void* IaAnyValue::operator new(size_t, IaAnyValue::allocate_new_value_st)
iaca.hh:667:7: error:                 static void* IaAnyValue::operator new(size_t, size_t, IaAnyValue::allocate_new_value_st)

Я не могу понять, каков правильный синтаксис для форсирования operator new.Я хочу, чтобы один из моего класса IaAnyValue был вызван в моей функции IaDictionnaryItem::make в конце моего iaca.hh файла

Я ввел пустой allocate_new_value, чтобы решить неоднозначность, но безуспешно.

Я безуспешно пытался

IaDictionnaryItem* IaDictionnaryItem::make() {
  return new(IaAnyValue::allocate_new_value) IaDictionnaryItem;
}

и

IaDictionnaryItem* IaDictionnaryItem::make() {
  return IaAnyValue::operator new(IaAnyValue::allocate_new_value) IaDictionnaryItem;
}

Из того, что я знаю, оператор new всегда вызывается с sizeof (* this) как неявный первымаргумент и т. д.

Некоторые мотивы, касающиеся моего вопроса, содержатся в этом вопросе о GC & C ++ компании Boehm .Пожалуйста, не говорите мне, что я не должен использовать ГК Бема.Мне нужно его использовать (иначе я не буду использовать C ++).

Какой правильный синтаксис заставляет вызывать хороший оператор new?

Я хочу, чтобы распределитель GC Boehm былиспользуемый.Он доступен через класс gc_cleanup, который находится в class IaItemValue : public IaAnyValue, gc_cleanup, а также как new в моем class IaAnyValue (единственный суперкласс IaDictionnaryItem). Я согласен, что есть двусмысленность, я просто неугадайте синтаксис, чтобы заставить его.

Так как мне написать мой тривиальный IaDictionnaryItem::make в конце файла, чтобы он был успешно скомпилирован?

Для удобства чтения я бы предпочел вызвать IaAnyValue::operator new с sz=sizeof(*this) т.е. sizeof(IaDictionnaryItem), gap=0 и al=allocate_new_value.Я просто не могу понять синтаксис, чтобы заставить этот конкретный вызываться (конечно, я все еще хочу, чтобы конструктор IaDictionnaryItem вызывался внутри IaDictionnaryItem::make).

Я пыталсяпринудительно gc::operator new(size_t size, GCPlacement gcp) (класс gc наследуется gc_cleanup от <gc/gc_cpp.h>) с использованием

IaDictionnaryItem* IaDictionnaryItem::make() {
  return new (UseGC) IaDictionnaryItem;
}

My make - статическая функция, возвращающая новый экземпляр моего объекта.Помните, что я использую GC Беома, и он в конечном итоге высвободит используемую память (и delete объект), когда на него не укажут указатели.

Но я все еще получаю

iaca.hh: In static member function 'static IaDictionnaryItem* IaDictionnaryItem::make()':
iaca.hh:962:22: error: request for member 'operator new' is ambiguous
/usr/local/include/gc/gc_cpp.h:304:14: error: candidates are: static void* gc::operator new(size_t, void*)
/usr/local/include/gc/gc_cpp.h:296:14: error:                 static void* gc::operator new(size_t, GCPlacement)
/usr/local/include/gc/gc_cpp.h:293:14: error:                 static void* gc::operator new(size_t)
iaca.hh:675:7: error:                 static void* IaAnyValue::operator new(size_t, IaAnyValue::allocate_new_value_st)
iaca.hh:667:7: error:                 static void* IaAnyValue::operator new(size_t, size_t, IaAnyValue::allocate_new_value_st)

С уважением.

РЕДАКТИРОВАТЬ: Вот простой пример проблемы:

#include <cstddef>
struct A {};
struct B { void* operator new(std::size_t, A); };

struct C {};
struct D { void* operator new(std::size_t, C); };

struct E : B, D {};

int main()
{
    //I want to use `void* D::operator new(std::size_t, C);` to allocate memory
    //but it will not compile because the call to operator new is ambiguous.
    new(C()) E;
}

Ответы [ 2 ]

4 голосов
/ 20 ноября 2011

Ваша проблема - проблема множественного наследования.Обратите внимание, что класс IaItemValue наследуется от IaAnyValue и gc_cleanupIaDictionnaryItem наследуется от IaItemValue), оба из которых обеспечивают перегрузки для operator new.Для решения этой проблемы вы можете добавить следующую строку в определение класса для IaDictionnaryItem:

using IaAnyValue::operator new;

2 голосов
/ 20 ноября 2011

Чтобы понять вашу проблему, я перебрал ваш код и могу сделать следующие утверждения:

  • IaAnyValue::allocate_new_value является struct allocate_new_value_st {}
  • GCPlacement является enum { NoGC, PointerFreeGC }

У вас есть три определенных new оператора:

void* operator new(size_t);               
void* operator new(size_t, GCPlacement);  
void* operator new(size_t, void*);        

Вы должны быть конкретны в отношении того, что вы называете.

Для звонка new(size_t):

new X;

Для звонка new(size_t, GCPlacement):

new(NoGC) X;

Для звонка new(size_t, void*):

allocate_new_value_st Y;
new(&Y) X;
...