(Obj) C ++: создание (ссылка на) класса из шаблона, доступ к его членам? - PullRequest
0 голосов
/ 11 июля 2009

Я пытаюсь что-то исправить в некотором коде Objective C ++ (?!). Я не знаю ни одного из этих языков, ни каких-либо соответствующих API или кодовой базы, поэтому у меня возникают проблемы влево и вправо.

Скажи, что у меня есть:

Vector<char, sizeof 'a'>& sourceData();
sourceData->append('f');

Когда я пытаюсь это скомпилировать, я получаю:

ошибка: запрос на член 'append' в 'WebCore :: sourceData', который имеет тип не-класса 'WTF :: Vector & () ();

В этом случае Vector - это WTF :: Vector (из WebKit или KDE или чего-то еще), а не STD :: Vector. append () очень часто считается членом класса, сгенерированного из этого шаблона, как видно из в этой документации . Это вектор. Он принимает тип, для которого создан шаблон.

Теперь, поскольку я никогда не пишу программы на языках программирования «Реального человека», я смущен тем, что обозначения для ссылок, указателей и разыменований и где они нам нужны.

В конечном итоге мне нужна ссылка на вектор, потому что я хочу передать ее другой функции с подписью:

void foobar(const Vector<char>& in, Vector<char>& out)

Я предполагаю, что const в sig foobar () - это то, что я могу игнорировать, что означает «не волнуйтесь, это не будет искажено, если вы передадите его здесь».

Я также пытался использовать .append, а не ->, потому что не относится ли к ссылкам на C ++ то, что вы можете относиться к ним больше как к указателям? В любом случае, это та же ошибка.

Я не совсем понимаю сообщение об ошибке: оно звучит так, как будто sourceData имеет тип WTF: Vector &, что мне и нужно. Из этих документов WTF :: Vector также видно, что когда вы создаете вектор чего-либо, вы получаете .append (). Но я не знаком с шаблонами, так что не могу сказать, что правильно читаю.

EDIT:

(Это долгое продолжение Павла Минаева) WOW СПАСИБО ЗАДАЧИ РЕШЕНО!

Я на самом деле просто писал правку к этому посту, в которой я частично понял вашу первую точку зрения после того, как натолкнулся на ссылку в Интернете, что эта строка сообщает компилятору о том, что вы ожидаете, объявив функцию sourceData (), которая не принимает никаких параметров и возвращает Вектор символов. поэтому «не относящийся к классу тип» в данном случае означает тип, который не является экземпляром класса. Я интерпретировал это как означающее, что тип не был «классом», т. Е. Типом вещи, которую вы ожидаете, вы можете вызвать как .addMethod (functionPointer).

Спасибо, хотя! То, что вы предлагаете, делает эту работу, я думаю. Так или иначе, я получил это в мою голову (idk откуда), что, поскольку func sig был вектором &, мне нужно было объявить их как & s. Как проблема стека против прохода кучи.

В любом случае, это была моя РЕАЛЬНАЯ проблема, потому что я попробовал то, о чем вы предлагали, но это не инициализировало ссылку. Вы должны явно вызывать конструктор, но затем, когда я помещаю что-либо в аргументы конструктора, чтобы избавиться от неоднозначности, являющейся прямым decl, он завершился неудачей с некоторой другой ошибкой о 'временном'.

Так что, в некотором смысле, я все еще не понимаю, что здесь происходит, но я от всего сердца благодарю вас за решение моей проблемы. если кто-то захочет дать какое-то дополнительное разъяснение для меня и будущих пользователей Google, это было бы здорово.

Ответы [ 2 ]

2 голосов
/ 11 июля 2009

Это:

 Vector<char, sizeof 'a'>& sourceData();

объявил глобальную функцию , которая не принимает аргументов и возвращает ссылку на Vector. Поэтому имя sourceData относится к типу функции. Когда вы пытаетесь получить доступ к члену этого, он справедливо жалуется, что это не класс / структура / объединение, и operator-> просто неприменимо.

Чтобы создать объект вместо этого, вы должны опустить круглые скобки (они требуются, только если у вас есть аргументы для передачи конструктору, и должны быть опущены, если их нет):

 Vector<char, sizeof 'a'> sourceData;

Тогда вы можете вызвать append:

 sourceData.append('f');

Обратите внимание, что точка используется вместо ->, потому что у вас есть объект, а не указатель на объект.

Вам не нужно делать ничего особенного, чтобы передать sourceData в функцию, которая хочет Vector&. Просто передайте переменную - она ​​будет передана по ссылке автоматически:

 foobar(sourceData, targetData);
0 голосов
/ 11 июля 2009

Погружение пальцев в C ++ никогда не доставляет большого удовольствия. В этом случае вы столкнулись с парой классических ошибок. Сначала вы хотите создать экземпляр Vector в стеке. В этом случае пустое () интерпретируется вместо этого как объявление функции с именем sourceData, которая не принимает никаких изменений и возвращает ссылку на Vector. Компилятор жалуется, что получающаяся функция не является классом (это не так). Чтобы создать экземпляр Vector, объявите его без () и удалите &. Скобки обязательны, только если вы передаете аргументы в конструктор экземпляра, и должны быть опущены, если аргументов нет.

Вы хотите

Vector<char, sizeof 'a'> sourceData;
sourceData.append('f');

Vector<char, sizeof 'a'> outData; //if outData is not instantiated already

foobar(sourceData, outData);

Эта статья в Википедии дает хорошее представление о ссылках на C ++.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...