Error reference to non static member function must be called

Вызов неопрелелнной функции в QT C++ Решение и ответ на вопрос 1402902

yaoman

0 / 0 / 0

Регистрация: 24.03.2015

Сообщений: 11

1

24.03.2015, 17:10. Показов 7167. Ответов 8

Метки нет (Все метки)


Здравствуйте. Помогите, пожалуйста, с проблемой : не могу вызвать метод из QMap.

mainwindiw.h:

C++ (Qt)
1
2
3
4
5
6
7
8
class MainWindow : public QMainWindow
{
    Q_OBJECT
 
public:
 
    void setText();
}

mainwindow.cpp:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
void MainWindow::setText() {
    ui->plainTextEdit->appendPlainText("Hello world!");
}
 
void MainWindow::on_pushButton_3_clicked()
{
    QMap <QString, void(*)()> mFunctions;
    mFunctions["setText"] = setText;
    mFunctions["setText"]();
}

Ошибки :

mainwindow.cpp:327: ошибка: reference to non-static member function must be called; did you mean to call it with no arguments?
mFunctions[«setText»] = setText;
^~~~~~~
()
mainwindow.cpp:327: ошибка: assigning to ‘void (*)()’ from incompatible type ‘void’
mFunctions[«setText»] = setText;
^ ~~~~~~~

Пытался заменить void(*)() множеством способов, но все равно выводит ошибки.
Расскажите, пожалуйста, работающий метод вызова функции по тексту в QT. Спасибо.

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



dzrkot

zzzZZZ…

527 / 358 / 94

Регистрация: 11.09.2013

Сообщений: 2,041

24.03.2015, 17:57

2

вот так будет работать, проблема будет если foo будет являться методом класса. Т.е. можно по идее просто сделать friend функции

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
void foo()
    {
    qDebug()<<"foo";
    }
Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
QMap <QString, void(*)()> mFunctions;
mFunctions["setText"] = foo;
mFunctions["setText"]();
}

ну или вот так, но как вызвать функция я не знаю сам

C++ (Qt)
1
2
3
4
5
6
7
Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
QMap <QString, void(Widget::*)()> mFunctions;
mFunctions["setText"] = foo;
mFunctions["setText"]();
}



0



0 / 0 / 0

Регистрация: 24.03.2015

Сообщений: 11

24.03.2015, 18:08

 [ТС]

3

К сожалению ваш способ не работает.



0



Croessmah

Don’t worry, be happy

17784 / 10550 / 2036

Регистрация: 27.09.2012

Сообщений: 26,538

Записей в блоге: 1

24.03.2015, 18:28

4

C++
1
2
3
4
QMap < int , std::function<void()> > mFunctions ;
 
mFunctions["setText"] = std::bind (&MainWindow::setText , *this) ;
mFunctions["setText"]();



0



0 / 0 / 0

Регистрация: 24.03.2015

Сообщений: 11

24.03.2015, 18:48

 [ТС]

5

В ключе QMap необходимо QString, а не int.
на bind выдает ошибку.
Попытался вызвать иные функции, предложенные IDE с bind. Так же ошибки.
Предложите, пожалуйста, иной работающий способ на QT.



0



MakeEasy

41 / 41 / 26

Регистрация: 24.02.2015

Сообщений: 151

24.03.2015, 19:21

6

Цитата
Сообщение от dzrkot
Посмотреть сообщение

ну или вот так, но как вызвать функция я не знаю сам

Вот так :

C++
1
2
3
4
5
    MainWindow mainWindow1;
    (mainWindow1.*(mFunctions["setText"]))();
    
    MainWindow *mainWindow2;
    (mainWindow2->*(mFunctions["setText"]))();



1



0 / 0 / 0

Регистрация: 24.03.2015

Сообщений: 11

24.03.2015, 19:29

 [ТС]

7

Ошбики(



0



MakeEasy

41 / 41 / 26

Регистрация: 24.02.2015

Сообщений: 151

24.03.2015, 19:34

8

Лучший ответ Сообщение было отмечено yaoman как решение

Решение

Вот так ошибка?

C++
1
2
3
4
5
6
void MainWindow::on_pushButton_3_clicked()
{
    QMap <QString, void(MainWindow::*)()> mFunctions;
    mFunctions["setText"] = &MainWindow::setText;
    (this->*(mFunctions["setText"]))();
}



2



0 / 0 / 0

Регистрация: 24.03.2015

Сообщений: 11

24.03.2015, 20:45

 [ТС]

9

Спасибо огромное!



0




Description


Wolfgang Bangerth



2004-09-13 14:19:57 UTC

(This is a spin-off from PR 17456) 
 
Take this code: 
----------------- 
struct S { 
  void foo(); 
  void bar() { foo; } 
}; 
----------------- 
Sure, the code looks odd: someone probably wanted to write foo() but 
forgot the parentheses. But I would think it is valid: we take a reference 
to the function S::foo and discard the result of this statement. But 
we get an error from gcc instead: 
 
g/x> /home/bangerth/bin/gcc-3.5-pre/bin/c++ -c x.cc 
x.cc: In member function `void S::bar()': 
x.cc:3: error: statement cannot resolve address of overloaded function 
 
That strikes me as completely odd and wrong: first, I think there shouldn't 
be an error in the first place; second, we certainly have no overloads 
here, so the message's intent is completely puzzling to me. Note that  
gcc2.95 printed this instead: 
 
g/x> /home/bangerth/bin/gcc-2.*/bin/c++ -c x.cc 
x.cc: In method `void S::bar()': 
x.cc:3: invalid use of member (did you forget the `&' ?) 
 
icc accepts the code without any warning or error. 
 
 
No, for comparison, think of the case where the two functions are 
non-members: 
------------------ 
void foo(); 
void bar() { foo; } 
------------------ 
Now we get 
 
g/x> /home/bangerth/bin/gcc-3.5-pre/bin/c++ -c x.cc 
x.cc: In function `void bar()': 
x.cc:2: warning: statement is a reference, not call, to function `foo' 
 
That makes more sense, and should have been what we get for the 
member case as well. 
 
W.


Comment 1


Giovanni Bajo



2004-09-13 17:33:12 UTC

Notice that you need "&S::foo" to take the address of a member function. The 
syntax "foo(blah)" is the function call syntax, and it is available only for 
function calls.

I am not sure why EDG accepts it. Anyway, our diagnostic is suboptimal.


Comment 2


Wolfgang Bangerth



2004-09-13 18:32:41 UTC

Uhm, yes... I tend to take icc's acceptance as standards conformance  
sometimes :-( 
 
W. 


Comment 3


Manuel López-Ibáñez



2010-02-21 19:07:51 UTC

More weirdeness.

// PR c++/17459: Spurious message when forgetting parentheses on call of member
// { dg-do compile }
struct S {
  void foo();
  void bar() { foo; } // { dg-error "statement cannot resolve address of overloaded function" }
  // { dg-message "note: taking the address of a member function requires the syntax '&S::foo'" "" { target *-*-* } 5 }
  void bar3() { &foo; } // { dg-error "ISO C.. forbids taking the address" }
  void * bar2() { return foo; }
};


This testcase produces:

pr17459.C: In member function 'void S::bar()':
pr17459.C:5:19: error: statement cannot resolve address of overloaded function
pr17459.C:5:19: note: taking the address of a member function requires the syntax '&S::foo'
pr17459.C: In member function 'void S::bar3()':
pr17459.C:7:18: error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function.  Say '&S::f
oo'
pr17459.C: In member function 'void* S::bar2()':
pr17459.C:8:26: error: argument of type 'void (S::)()' does not match 'void*'


The last one really kills me. It should be the same error as the first one, isn't it? 

Oh, I give up on this one!


Comment 4


Paolo Carlini



2013-05-16 17:09:35 UTC

Manuel can you help me reassessing this? I think we are doing much better.


Comment 5


Manuel López-Ibáñez



2013-05-16 17:26:42 UTC

(In reply to Paolo Carlini from comment #4)
> Manuel can you help me reassessing this? I think we are doing much better.

I get this:

test.cc:3:19: error: invalid use of non-static member function
   void bar() { foo; } 
                   ^
 void S::bar3()
test.cc:5:18: error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function.  Say ‘&S::foo’ [-fpermissive]
   void bar3() { &foo; } 
                  ^
 void* S::bar2()
test.cc:6:26: error: cannot convert ‘S::foo’ from type ‘void (S::)()’ to type ‘void*’
   void * bar2() { return foo; }
                          ^

The first error could be a bit nicer if it said why it is invalid. Clang does:

test.cc:3:16: error: reference to non-static member function must be called; did you mean to call it with no arguments?

but the thing is that this is not even a valid reference, so the error could clarify a bit more the problem, no?

ISO C++ forbids taking the address of an unqualified non-static member function, say ‘&S::foo’ instead; or did you mean to call 'foo()'?

The last error is bogus, it should be the same as the first one. Clang gives two errors, but at least the first is the correct one:

test.cc:6:26: error: reference to non-static member function must be called; did you mean to call it with no arguments?
  void * bar2() { return foo; }
                         ^~~
                            ()
test.cc:6:26: error: cannot initialize return object of type 'void *' with an rvalue of type 'void'
  void * bar2() { return foo; }
                         ^~~~


Comment 6


Jonathan Wakely



2021-07-15 20:38:15 UTC

(In reply to Manuel López-Ibáñez from comment #5)
> The first error could be a bit nicer if it said why it is invalid. Clang
> does:
> 
> test.cc:3:16: error: reference to non-static member function must be called;
> did you mean to call it with no arguments?

I think we should just add a fix-it hint suggesting to add the ()


> but the thing is that this is not even a valid reference, so the error could
> clarify a bit more the problem, no?

I don't think mentioning "reference" here is a good idea at all, because that means something specific in C++ (and completely unrelated to this).

I prefer GCC's "invalid use" wording. With a fix-it to add the () the error would be fine.

If the function can't be called with no arguments, the fix-it would be wrong. I'm not sure what we want to do in that case. Suggest the fix-it anyway, and let the user figure out the next step?

Clang just says:

17459-c3.C:3:16: error: reference to non-static member function must be called

i.e. it omits the "did you mean to call it with no arguments?" part. So we could do the same and just not provide a fix-it in that case.


> ISO C++ forbids taking the address of an unqualified non-static member
> function, say ‘&S::foo’ instead; or did you mean to call 'foo()'?

Maybe we should remove the -fpermissive extension that allows &foo as a non-standard way to form a pointer-to-member. That simplifies the handling of &foo, because we can just reject it instead of using a permerror. It's more than 20 years since that was acceptable syntax.

And that could use a fix-it hint too, to suggest turning &foo into &S::foo.


> The last error is bogus, it should be the same as the first one.

Agreed.

проблема в создании класса

Offline

Зарегистрирован: 09.08.2015

Хочу создать клас RFID ридера. Не могу назначить функцию прерывания для элемента класса (функция PCattachInterrupt).

Идея: При обявлении класса нужно зарегестрировать ф-ции прерывания для вывода D0 и D1. Теоретически программа должна для каждого экземпляра класа создать свои две ф-ции прерывания, потому this должен указать на конкретный экземпляр и соответственно на конкретную ф-цию, но не работает.

Гуру С++ помогите решыть проблему!

Ошибка: 

error: reference to non-static member function must be called; did you mean to call it with no arguments?

        PCattachInterrupt(_D1_pin, this->readerOne, CHANGE);
                                   ~~~~~~^~~~~~~~~
libraries/PinChangeInt/PinChangeInt.h:163:78: note: expanded from macro 'PCattachInterrupt'
#define PCattachInterrupt(pin,userFunc,mode) PCintPort::attachInterrupt(pin, userFunc,mode)
                                                                             ^

 rdrRFID.cpp:37:29: error: cannot initialize a parameter of type 'PCIntvoidFuncPtr' (aka 'void (*)()') with an rvalue of type 'void'

        PCattachInterrupt(_D1_pin, this->readerOne, CHANGE);
                                   ^~~~~~~~~~~~~~~

КОД:

/*

  ReaderRFID.cpp - библиотека для ридера с интерфейсом WIEGAND 26
  Версия 1.0
*/
 
#include "rdrRFID.h"
#include <PinChangeInt.h>
 
rdrRFID::rdrRFID(int _D0, int _D1)
{
	_D0_pin = _D0;
	_D1_pin = _D1;
	
	reader = 0;
	_readerCount = 0;
}
 
void rdrRFID::readerOne(void) {
  if(digitalRead(_D1_pin) == LOW){
  _readerCount++;
  reader = reader << 1;
  reader |= 1;
  }
}

void rdrRFID::readerZero(void) {
  if(digitalRead(_D0_pin) == LOW){
  _readerCount++;
  reader = reader << 1;  
  }
}
  
void rdrRFID::initReader(void){
//инициализация
//установка прерывания на портах контроллера
	PCattachInterrupt(_D1_pin, this->readerOne, CHANGE);
	PCattachInterrupt(_D0_pin, this->readerZero, CHANGE);
//установка направления порта
	int arr_pin_reader[2]={_D0_pin, _D1_pin};
	for(int i = 0; i < 2; i++)
	{
		pinMode(arr_pin_reader[i], OUTPUT);
		digitalWrite(arr_pin_reader[i], HIGH);
		digitalWrite(arr_pin_reader[i], LOW); 
		pinMode(arr_pin_reader[i], INPUT);
		digitalWrite(arr_pin_reader[i], HIGH); 
	}
}

Понравилась статья? Поделить с друзьями:
  • Error reading the license file could not parse certificate java io ioexception odis
  • Error reading stick
  • Error reading result file you should use exception handling concepts
  • Error reading prometheus an error occurred within the plugin
  • Error reading comcombobox1