Форум программистов, компьютерный форум CyberForum.ru

разобраться с ошибкой с3867 (msvs 2012) - C++

Восстановить пароль Регистрация
 
proech
10 / 10 / 2
Регистрация: 10.07.2013
Сообщений: 150
07.12.2013, 18:56     разобраться с ошибкой с3867 (msvs 2012) #1
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include "stdafx.h"
#include "Menu.h"
#include "Labs.h"
void Some(){std::cout<<"спасибо что работает ";_getch();}
 
int main()
{int n =5;
setlocale(LC_ALL,"Russian");
 
    Menu M(n);
    First i1;
    void (*Process)() = i1.Do();
    MenuItem * a = new MenuItem[n];
    M.gotoXY(0,3);
    M.Color(15,0);
    a[0].SetProcess(Some);
    a[0].SetTitle("                                           классы                                          ");
        a[1].SetTitle("                             Использование динамических списков       ");
    a[2].SetTitle("                                    перегрузка операторов                       ");
    a[3].SetTitle("                                        наследование                                  ");
    a[4].SetTitle("                                           выход                                           ");
    a[1].SetProcess(Process);
    a[2].SetProcess(Some);
    a[3].SetProcess(Some);
    a[4].SetProcess(Some);
    
    M.AddItems(n,a[0],a[1],a[2],a[3],a[4]);
    M.ShowMenu();
getchar();
    return 0;
}
Ошибка 1 error C3867: First:: Do: в вызове функции отсутствует список аргументов; используйте "&First:: Do" для создания указателя на член
файлы #include
Вложения
Тип файла: rar ConsoleApplication102.rar (2.8 Кб, 3 просмотров)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.12.2013, 18:56     разобраться с ошибкой с3867 (msvs 2012)
Посмотрите здесь:

C++ Не могу разобраться с ошибкой в проге
C++ Конвертировать с MsVS 2008 в MsVS 2010
пом0гите разобраться с ошибкой C++
не могу разобраться с ошибкой C++
C++ MSVS 2012: fstream не открывает файл при дебаге
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
07.12.2013, 19:17     разобраться с ошибкой с3867 (msvs 2012) #2
Вот это что?
C++
1
void (*Process)() = i1.Do();
proech
10 / 10 / 2
Регистрация: 10.07.2013
Сообщений: 150
07.12.2013, 23:11  [ТС]     разобраться с ошибкой с3867 (msvs 2012) #3
я пытался создать ссылку на функцию
работает с void -ами но с методами класса почему-то отказывается
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
07.12.2013, 23:22     разобраться с ошибкой с3867 (msvs 2012) #4
Цитата Сообщение от proech Посмотреть сообщение
я пытался создать ссылку на функцию
Указатель на метод не так объявляется:
C++
1
void (First::*Process)() = &First::Do;
И как вы потом его использовать собираетесь? SetProcess() принимает указатель на функцию, не на метод.
proech
10 / 10 / 2
Регистрация: 10.07.2013
Сообщений: 150
07.12.2013, 23:23  [ТС]     разобраться с ошибкой с3867 (msvs 2012) #5
а как сделать что-бы на метод класса указывало?
не увидел предыдущий комментарий
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
07.12.2013, 23:28     разобраться с ошибкой с3867 (msvs 2012) #6
тип "указатель на метод" отличается от типа "указатель на свободную функцию"
и работают с ними не так, как с указателями на функции.
есть еще std::function и в них можно завернуть как указатель на свободную функцию,
так и указатель на метод определенного объекта

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include "stdafx.h"
 
#include <functional>
#include <iostream>
#include <string>
 
struct Test
{
  std::string name;
 
  Test(const std::string& testName)
    : name(testName)
  {
  }
 
  void Foo1()
  {
    std::cout << name << "::Foo1" << std::endl;
  }
 
  void Foo2()
  {
    std::cout << name << "::Foo2" << std::endl;
  }
};
 
void MyFunction()
{
  std::cout << "This is my function" << std::endl;
}
 
 
int main()
{
  void (Test::*memFunPtr)() = &Test::Foo1; // можно так, но лучше затайпдефить
 
  typedef void (Test::* MemFunPtr)();
 
  MemFunPtr ptr1 = &Test::Foo1;
  MemFunPtr ptr2 = &Test::Foo2;
  // тут для получения указателя на метод не нужен сам объект.
  // он понадобится, когда нужно будет вызвать метод.
  // И имея один и тот же указтель на метод, можно
  // этот метод позвать у разных объектов:
 
  Test test1("Test1");
  Test test2("Test2");
 
  (test1.*ptr1)();
  (test1.*ptr2)();
 
  (test2.*ptr1)();
  (test2.*ptr2)();
 
 
  typedef std::function<void ()> Func;
 
  Func func;
 
  func = &MyFunction;
  func();
 
  func = std::bind(&Test::Foo1, &test1);
  func();
 
  func = [&test2] { test2.Foo2(); };
  func();
 
  return 0;
}
proech
10 / 10 / 2
Регистрация: 10.07.2013
Сообщений: 150
08.12.2013, 00:40  [ТС]     разобраться с ошибкой с3867 (msvs 2012) #7
все равно ничего не выходит
C++
1
2
3
4
typedef void(First::*Method)();
Method _ptr = &First::Do;
 
a[0].SetProcess(_ptr);
как мне переписать функцию setProcess чтобы работало и с void - ами и с методами класса?
а что такое std::bind?
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
08.12.2013, 01:26     разобраться с ошибкой с3867 (msvs 2012) #8
void - ами и с методами класса
это означает и с указателями на методы и с указателями на свободные функции? или что-то другое?

я не совсем понял задачу в целом. если вам в какую-то функцию или метод нужно передать что-то, что
можно выполнить, то есть классический подход (смотрите паттерны проектирования Command, Strategy):
То, что нужно выполнить оформляется в абстрактного класса и в потомках уже делается конкретная реализация.
C++
1
2
3
4
class Command
{
   virtual void Execute() = 0;
};
В наследниках вы реализуете Execute вызовом свободной функции или вызовом метода какого-то объекта или еще как захотите.
В функцию setProcess передается указатель на Command, а внутри происходит вызов Execute.

В новом стандарте появился шаблон std::function, которым можно заменить подобные абстрактные классы с
одной функцией. И чтобы это заработало, сигнатура вашего setProcess должна быть такой:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// вариант для свободной функции, для метода - аналогично:
void setProcess(std::function<void ()> command)
{
  ...
  command();
  ...
}
 
// и дальше где-то в коде можно вызывать
  std::function<void ()> func;
  func = &MyFunction;
  setProcess(func);
 
   // или без промежуточных объектов сразу:
  setProcess(&MyFunction);
  setProcess(std::bind(&Test::Foo1, &test1));
  setProcess([&test2] { test2.Foo2(); });
Что такое std::bind - лучше доки почитать.
если вкратце - то это функция, которая возвращает объект с перегруженным оператором ().
при вызове этого оператора в примере происходит вызов метода у объекта, которые были
переданы как аргументы в функцию std::bind
proech
10 / 10 / 2
Регистрация: 10.07.2013
Сообщений: 150
08.12.2013, 21:55  [ТС]     разобраться с ошибкой с3867 (msvs 2012) #9
всё равно выдаёт ошибку
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
08.12.2013, 21:59     разобраться с ошибкой с3867 (msvs 2012) #10
А код где, который
Цитата Сообщение от proech Посмотреть сообщение
всё равно выдаёт ошибку
?
Ясновидящих тут нет.
proech
10 / 10 / 2
Регистрация: 10.07.2013
Сообщений: 150
08.12.2013, 22:26  [ТС]     разобраться с ошибкой с3867 (msvs 2012) #11
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include "stdafx.h"
#include "Menu.h"
 
#include <iostream>
 
 
int main()
{
    
 
 int n =5;
setlocale(LC_ALL,"Russian");
Menu M(n);
typedef void (Menu::*Method)();
Method _ptr = &Menu::Exit;
MenuItem a,b,c,d,e;
M.gotoXY(0,5);
M.Color(15,0);
a.SetTitle(" динамические структуры ");
b.SetTitle(" классы  ");
c.SetTitle(" перегрузка операторов  ");
d.SetTitle(" наследование ");
e.SetTitle(" Выход ");
a.SetProcess(FirstLab);
b.SetProcess(Second);
c.SetProcess(Three);
d.SetProcess(Four);
e.SetProcess(_ptr);// вот здесь выдаёт ошибку с3867
/*
Ошибка  1   error C3867: Menu::Exit: в вызове функции отсутствует список аргументов; используйте "&Menu::Exit" для создания указателя на член   
*/
 
M.AddItems(n,a,b,c,d,e);
 
M.ShowMenu();
getchar();
    return 0;
}
Вложения
Тип файла: rar program.rar (6.1 Кб, 1 просмотров)
proech
10 / 10 / 2
Регистрация: 10.07.2013
Сообщений: 150
08.12.2013, 22:31  [ТС]     разобраться с ошибкой с3867 (msvs 2012) #12
пытался сделать так
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// ConsoleApplication102.cpp: определяет точку входа для консольного приложения.
//
 
#include "stdafx.h"
#include "Menu.h"
 
#include <iostream>
 
 
int main()
{
    
 
 int n =5;
setlocale(LC_ALL,"Russian");
Menu M(n);
typedef void (Menu::*Method)();
Method _ptr = &Menu::Exit;
MenuItem a,b,c,d,e;
M.gotoXY(0,5);
M.Color(15,0);
a.SetTitle(" динамические структуры ");
b.SetTitle(" классы  ");
c.SetTitle(" перегрузка операторов  ");
d.SetTitle(" наследование ");
e.SetTitle(" Выход ");
a.SetProcess(FirstLab);
b.SetProcess(Second);
c.SetProcess(Three);
d.SetProcess(Four);
//
e.SetProcess((M.*_ptr));//
//
M.AddItems(n,a,b,c,d,e);
 
M.ShowMenu();
getchar();
    return 0;
}
но
IntelliSense: указатель на привязанную функцию можно использовать только для вызова функции
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
08.12.2013, 22:37     разобраться с ошибкой с3867 (msvs 2012) #13
Вы что-нибудь поняли из того, что вам DU объяснял?
Цитата Сообщение от DU Посмотреть сообщение
есть еще std::function и в них можно завернуть как указатель на свободную функцию,
так и указатель на метод определенного объекта
proech
10 / 10 / 2
Регистрация: 10.07.2013
Сообщений: 150
08.12.2013, 22:41  [ТС]     разобраться с ошибкой с3867 (msvs 2012) #14
если честно то не очень)
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
08.12.2013, 22:42     разобраться с ошибкой с3867 (msvs 2012) #15
Если сигнатуру вы написали как я писал до этого, то:
C++
1
2
3
4
5
e.SetProcess(std::bind(_ptr, &M));
// или
e.SetProcess(std::bind(&Menu::Exit, &M));
// или же лямбдой более понятно:
e.SetProcess([&M] { M.Exit();} );
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
08.12.2013, 22:51     разобраться с ошибкой с3867 (msvs 2012) #16
Цитата Сообщение от proech Посмотреть сообщение
если честно то не очень)
Пути, по-моему, два: или понять, или решать задачу другим способом.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.12.2013, 23:16     разобраться с ошибкой с3867 (msvs 2012)
Еще ссылки по теме:

C++ Не могу разобраться с ошибкой
C++ Не могу разобраться с ошибкой
C++ MSVS 2012 error LNK2019: unresolved external symbol

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
proech
10 / 10 / 2
Регистрация: 10.07.2013
Сообщений: 150
08.12.2013, 23:16  [ТС]     разобраться с ошибкой с3867 (msvs 2012) #17
Ошибка 1 error C2664: std::_Func_class<_Ret>::_Set: невозможно преобразовать параметр 1 из "_Myimpl *" в "std::_Func_base<_Rx> *"

C++
1
2
3
4
5
6
7
8
class Menu{
...
std::function<void()> Process
 
void SetProcess(std::function<void()> Command){Process = Command;}
...
 
}
основная
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include "stdafx.h"
#include "Menu.h"
#include <functional>
#include <iostream>
 
 
int main()
{
    
 
 int n =5;
setlocale(LC_ALL,"Russian");
Menu M(n);
typedef void (Menu::*Method)();
Method _ptr = &Menu::Exit;
MenuItem a,b,c,d,e;
M.gotoXY(0,5);
M.Color(15,0);
a.SetTitle(" динамические структуры ");
b.SetTitle(" классы  ");
c.SetTitle(" перегрузка операторов  ");
d.SetTitle(" наследование ");
e.SetTitle(" Выход ");
a.SetProcess(FirstLab);
b.SetProcess(Second);
c.SetProcess(Three);
d.SetProcess(Four);
e.SetProcess(_ptr);
 
M.AddItems(n,a,b,c,d,e);
 
M.ShowMenu();
getchar();
    return 0;
}
Добавлено через 4 минуты
ура заработало)))
забыл
C++
1
e.SetProcess(std::bind(&Menu::Exit,&M));
Добавлено через 12 минут
спасибо всем за помощь))
Yandex
Объявления
08.12.2013, 23:16     разобраться с ошибкой с3867 (msvs 2012)
Ответ Создать тему
Опции темы

Текущее время: 15:44. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru