#include<iostream>
class name
{
public:
int a;
name():a(0){};
};
void add(name * pname)
{
pname = NULL;
}
int main()
{
name varName();
name * pName = new name();
add(pName);
add(&varName);//error C2664: 'add' : cannot convert parameter 1 from 'name __cdecl *)(void)' to 'name *'
}





Ошибка находится в первой строке основной функции:
name varName();
Вы нет создаете экземпляр класса название с конструктором по умолчанию, вы фактически объявляете новую функцию с именем varName без параметров, которая возвращает экземпляр название.
Вместо этого вы должны написать:
name varName;
мне так нравятся вопросы такого рода :) это вызывает "ага!" влияет на читателей, и дает много очков за правильный ответ :) +1 действительно
есть ли что-то похожее на этот синтаксис в C++ ... что нужно знать abt
rajKumar, другой пример см. ниже
Мой разум был ошеломлен. Я никогда не сталкивался с этим за годы использования C++, но это определенно +1.
name varName();
интерпретируется как объявление локальной функции. Чтобы вызвать конструктор по умолчанию, используйте
name varName;
вместо. Очень досадно, да.
Думаю, стоит рассказать о подобной проблеме, тоже доставляющей неприятности:
struct foo { };
struct bar { bar(foo f); };
int main() {
// does *not* create a bar object initialized by a default constructed
// foo object.
bar b(foo());
}
На самом деле b - это функция, которая возвращает bar и принимает в качестве первого аргумента указатель на функцию, которая возвращает foo без аргументов. Это то же самое, что:
bar b(foo(*)());
Если вы хотите создать объект bar, инициализированный сконструированным по умолчанию foo, заключите аргумент в круглые скобки. Это делает его больше не похожим на объявление функции, и компилятор будет интерпретировать его так, как вы хотите:
bar b((foo()));
Также существуют неочевидные случаи, когда должна возникать ошибка компилятора. GCC ошибается, но Комо снова все делает правильно. Рассмотрим следующий фрагмент
struct foo {
static bool const value = false;
};
int main() {
int v(int(foo::value));
}
Вы, вероятно, ожидаете, что он берет статическую константу и преобразует ее в int, инициализируя переменную v в 0? Нет, это не будет соответствовать Стандарту, потому что инициализатор можно интерпретировать как объявление в соответствии с чистым синтаксическим анализом, как показано ниже.
struct foo {
static int value;
};
// valid, parentheses are redundant! Defines `foo::value`.
int (foo::value);
Всякий раз, когда инициализатор можно интерпретировать как объявление, в такой ситуации все объявление будет объявлять функцию. Итак, строка в main объявляет функцию, подобную следующей, без лишних и бессмысленных круглых скобок.
int v(int foo::value);
И это вызовет ошибку компилятора при синтаксическом анализе объявления функции, поскольку имя параметра функции может быть неквалифицированным.
Отлично отвечая на мой следующий вопрос ... даже прежде, чем задать его
@litb определяет, что параметр функции передается по значению или по ссылке, это просто сигнатура функции или как функция вызывается
rajKumar, я ранее отвечал на этот вопрос, пытаясь дать ему определение: stackoverflow.com/questions/410593/…. или вы имеете в виду другое?
Ага. то же самое только в списках параметров. в противном случае foo () действительно является типом функции, а не типом указателя функции (подобно тому, как char [3] является типом массива, а char (*) [4] - указателем массива)
Также стоит отметить, что ваша функция add () не имеет длительного эффекта - все, что она делает, это присваивает значение pname, которое является копией переданного вами указателя. Если вы действительно хотите иметь эту палку присваивания, вам нужно будет передать указатель по ссылке как «name * & pname».
Я сталкивался с этим тысячу раз! ;-) <troll> Я думаю, что язык C++ - это успешный «мем» (проверьте Википедию): он успешен, потому что позволяет разработчикам чувствовать себя умными, когда они наконец поймут еще одну проблему. Им это льстит, поэтому им это нравится. ;-) </troll>