Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> непонятка с конструкторами и указателями на ф-ии 
V
    Опции темы
Alek86
Дата 25.2.2008, 11:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



есть код
Код

typedef void (*Func)(const int&);

void func(const int& i) {
  PRINT_VALUE(i);
};

struct Functor {
  Functor(Func iop_func) : mp_func(iop_func) {}
  void operator()(const int& i) {
    mp_func(i);
  };
private:
  Func mp_func;
};

int main() {
  Functor f = Functor(func); // 1
  Functor(func);                   // 2
  system("pause");
}


строка // 1 нормально компилится
на строку //2 ругается: error C2512: 'Functor' : no appropriate default constructor available

понимаю, что прикол тут из легких, но не вижу. может, кто объяснит?


--------------------
user posted image    user posted image
PM MAIL   Вверх
jorikdima
Дата 25.2.2008, 12:04 (ссылка)   | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 107
Регистрация: 18.1.2008
Где: Там, где Зенит

Репутация: нет
Всего: нет



удалил

Это сообщение отредактировал(а) jorikdima - 25.2.2008, 12:09
PM MAIL   Вверх
Fazil6
Дата 25.2.2008, 12:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 35
Всего: 60



Цитата(Alek86 @  25.2.2008,  10:43 Найти цитируемый пост)
на строку //2 ругается: error C2512: 'Functor' : no appropriate default constructor available

а что ты пытаешься изобразить строкой
Код

 Functor(func);                   // 2

???
PM MAIL   Вверх
Alek86
Дата 25.2.2008, 12:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



Цитата(Fazil6 @  25.2.2008,  12:07 Найти цитируемый пост)
а что ты пытаешься изобразить строкой

создать временный объект типа Functorб передавая ему в качестве аргумента указатель на ф-ю

ЗЫ. Кстати, ведь неважно, что я хочу сделать, вопрос же не "а почему оно не так работает" smile


Цитата(jorikdima @  25.2.2008,  12:04 Найти цитируемый пост)
Добавте дефолтовый конструктор (без параметров) в структуру. Пусть он хоть ничего не делает, но объевлен быть должен.

должен? аргументируй smile


--------------------
user posted image    user posted image
PM MAIL   Вверх
Fazil6
Дата 25.2.2008, 12:28 (ссылка)  | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 35
Всего: 60



думаю, что дело в том, что компилятор не может такое выражение правильно разобрать (то, что ты имеешь в виду).
попробуй вот так
Код

Functor::Functor(func);                   // 2


Добавлено через 2 минуты и 25 секунд
Цитата(Alek86 @  25.2.2008,  11:11 Найти цитируемый пост)
создать временный объект типа Functorб передавая ему в качестве аргумента указатель на ф-ю

ведь вызов конструктора - это не создание объекта, а инициализация объекта
PM MAIL   Вверх
Alek86
Дата 25.2.2008, 12:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



Цитата(Fazil6 @  25.2.2008,  12:28 Найти цитируемый пост)
попробуй вот так

помогло, спасибо

Цитата(Fazil6 @  25.2.2008,  12:28 Найти цитируемый пост)
думаю, что дело в том, что компилятор не может такое выражение правильно разобрать

онлайн компилятор (других не имею) написал то же самое:
Цитата

C/C++ Front-end Compiler & Virtual Machine, Version 3.0.
Copyright © 1998-2003, Interstron, Ltd.

*** C++ FrontEnd
D:\soft\compiler\tmp\test.cpp.9 (18, 3): error 0417: Class 'class Functor' has no default constructor


то есть эта "фича" согласована со Стандартом?

Цитата(Fazil6 @  25.2.2008,  12:28 Найти цитируемый пост)
ведь вызов конструктора - это не создание объекта, а инициализация объекта

имхо, неверно
Код

struct S{};

int main() {
  S();
}

тут создается временный объект и сразу умирает


--------------------
user posted image    user posted image
PM MAIL   Вверх
Daevaorn
Дата 25.2.2008, 12:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Цитата(Fazil6 @  25.2.2008,  13:28 Найти цитируемый пост)

ведь вызов конструктора - это не создание объекта, а инициализация объекта 

хороший перлsmile и назван конструктор "конструктором" по ошибке, да?
PM MAIL WWW   Вверх
Alek86
Дата 25.2.2008, 12:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



Цитата(Daevaorn @  25.2.2008,  12:38 Найти цитируемый пост)
хороший перл

не перл, если имелось в виду невыделение памяти

ведь new вызывает конструктор для уже выделенной памяти
просто в стеке вместо new память выделяет среда выполнения

Добавлено через 2 минуты и 51 секунду
кстати вопрос еще в силе, хоть и чуток изменен
это "Стандартное" поведение компилятора?


--------------------
user posted image    user posted image
PM MAIL   Вверх
Daevaorn
Дата 25.2.2008, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Цитата(Alek86 @  25.2.2008,  13:42 Найти цитируемый пост)
не перл, если имелось в виду невыделение памяти

ведь new вызывает конструктор для уже выделенной памяти
просто в стеке вместо new память выделяет среда выполнения 

для тебя "создание объекта" и "выделенение памяти" одно и тоже?smile Второй перлsmile
PM MAIL WWW   Вверх
Alek86
Дата 25.2.2008, 12:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



для меня "создание объекта" делится на "выделение памяти" и "инициализацию"
читай внимательней

или это третий перл?
тогда уж потрудись объяснить как На Самом Деле, когда из под стола вылезешь smile


--------------------
user posted image    user posted image
PM MAIL   Вверх
Mayk
Дата 25.2.2008, 12:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


^аВаТаР^ сообщение>>
****


Профиль
Группа: Участник
Сообщений: 2616
Регистрация: 22.5.2005
Где: за границей разум а

Репутация: 45
Всего: 134



Цитата(Alek86 @  25.2.2008,  16:42 Найти цитируемый пост)

кстати вопрос еще в силе, хоть и чуток изменен
это "Стандартное" поведение компилятора? 

Судя по всему да.  Можно же делать int a( int (x) );
вот и тут похоже то же самое.

Тем более что если внести прототип ф-ции в main() то ошибка уже 
Цитата

"ComeauTest.c", line 15: error: "func" has already been declared in the current
          scope
    Functor(func);                   // 2


Это сообщение отредактировал(а) Mayk - 25.2.2008, 13:00


--------------------
 Здесь был кролик. Но его убили.
Человеки < кроликов, йа считаю.
PM MAIL WWW ICQ   Вверх
Alek86
Дата 25.2.2008, 13:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



Цитата(Mayk @  25.2.2008,  12:58 Найти цитируемый пост)
Можно же делать int a( int (x) );

а при чем тут int a( int (x) ) ?
наоборот, тут МОЖНО вызвать int(x) (создание временного объекта)


в моем же случае вызвать не получается

Добавлено через 1 минуту и 10 секунд
кстати
Код
int('s');

спокойно сьедает и не давится


--------------------
user posted image    user posted image
PM MAIL   Вверх
Mayk
Дата 25.2.2008, 13:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


^аВаТаР^ сообщение>>
****


Профиль
Группа: Участник
Сообщений: 2616
Регистрация: 22.5.2005
Где: за границей разум а

Репутация: 45
Всего: 134



Код

typedef void (*Func)(const int&);
void func(const int& i) {
}

struct Functor {
  Functor(Func iop_func) : mp_func(iop_func) {}
  void operator()(const int& i) {
    mp_func(i);
  };
private:
  Func mp_func;
};

int main() {
  Functor f = Functor(func); // 1
  Functor((Func)func);                   // 2

}

вот так компилятор тоже понимает что  //2 ни разу не объявляет переменную под названием func

Добавлено @ 13:05
Цитата(Alek86 @  25.2.2008,  17:01 Найти цитируемый пост)



в моем же случае вызвать не получается

Какой вызов? О чем ты? Нет там никакого вызова акромя неявного вызова конструктора по умолчания. Там определятся переменная func с типом Functor. И компилятор не может найти дефолтовый конструктор. О чем и сообщает.

А у int(x) с конструированием по умолчанию проблем нет. В отличие от Functor'а.

Это сообщение отредактировал(а) Mayk - 25.2.2008, 13:06


--------------------
 Здесь был кролик. Но его убили.
Человеки < кроликов, йа считаю.
PM MAIL WWW ICQ   Вверх
Alek86
Дата 25.2.2008, 13:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



хм
если есть переменная  func типа Func, разве не должен компилятор (используя поиск-не-помню-кого) найти конструктор, который принимает переменную типа Func и заюзать его?


--------------------
user posted image    user posted image
PM MAIL   Вверх
Fazil6
Дата 25.2.2008, 13:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 35
Всего: 60



Цитата(Daevaorn @  25.2.2008,  11:38 Найти цитируемый пост)
хороший перл и назван конструктор "конструктором" по ошибке, да?


Цитата

12.1.2
A constructor is used to initialize objects of its class type. Because constructors do not have names, they
are never found during name lookup; however an explicit type conversion using the functional notation
(5.2.3) will cause a constructor to be called to initialize an object. [Note: for initialization of objects of
class type see 12.6. ]

вообще стандарт - сборник перлов. 
Создание объекта - выделение памяти + вызов конструктора.

пробуем выполнить вот такую программу и многое становится ясно
Код

#include <iostream>

typedef void (*Func)(const int&);

void func(const int& i) {
    
};

class A
{
public:
    A()
    {
        std::cout << "A::A()\n";
    }
};

struct Functor {
    Functor(Func iop_func) /*: mp_func(iop_func) */
    {
        std::cout << "Functor::Copy\n"; 
    }
    Functor()
    {std::cout << "Functor::Def\n"; };
    f()
    {
        std::cout << "Functor::f\n";
    }
    void operator()(const int& i) {
        mp_func(i);
    };
private:
    Func mp_func;
    A a;
};

int main() {
    
    Functor(func);  // 2
    func.f();
    

}


По сути вопроса смотрим стандарт пункт 6.8 Ambiguity resolution

Functor(func);  // 2  - это тоже самое что и  Functor func ;

PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0760 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.