我有问题将成员函数指针传递给gcc上的模板化成员函数.有谁知道如何修改下面的代码让gcc接受我想要做的事情?
class Foo
{
public:
template <class C, class R>
void Execute(R(typename C::*memFn)())
{
}
};
Run Code Online (Sandbox Code Playgroud)
尝试编译代码时出现以下错误:
test.cpp:40: error: 'memFn' was not declared in this scope
test.cpp:40: error: expected primary-expression before '(' token
test.cpp:40: error: expected identifier before '*' token
test.cpp:40: error: expected '(' before '*' token
test.cpp:40: error: 'memFn' was not declared in this scope
test.cpp:40: error: variable or field 'Execute' declared void
Run Code Online (Sandbox Code Playgroud)
我使用的gcc版本是4.4.2.
非常感谢您的帮助!
我有一个C++类,简而言之,它有一个如下所示的声明:
class Pico {
...
Document document; // Custom Document class
...
}
Run Code Online (Sandbox Code Playgroud)
后来我调用了Document该类的一个公共成员函数:
this->document->enableEditing();
Run Code Online (Sandbox Code Playgroud)
但是,IntelliSense强调this并注意到"表达式必须具有指针类型".我该怎么做才能解决这个问题?
每个使用此调用进行扩展的类都会在析构函数中中止,并且调用堆栈告诉我调用abort的函数是从头文件中的不合理的位置调用的.其他函数被覆盖并且工作正常.
Renderable.h
#pragma once
class Renderable
{
public:
virtual void update(long delta) = 0;
virtual void destroy() = 0;
virtual void render() = 0;
virtual ~Renderable();
};
Run Code Online (Sandbox Code Playgroud)
Renderable.cpp
#include "Renderable.h"
Renderable::~Renderable()
{
(this->*(&Renderable::destroy))(); // GLUtils::runOnUIThreadWithContext(this, &Renderable::destroy, true);
} // It says that it gets called from here.
Run Code Online (Sandbox Code Playgroud)
我有一堆遗留代码,如下所示:
#define MAKE_FOO_FNS(fooname) \
fooname* makeFoo_ ## fooname ## A(A arg) { \
return new fooname(arg); \
} \
fooname* makeFoo_ ## fooname ## B(B arg) { \
return new fooname(arg); \
} \
// ... repeated many more times
Run Code Online (Sandbox Code Playgroud)
所以我们可以在后面的代码中说:
MAKE_FOO_FNS(FooType1);
MAKE_FOO_FNS(FooType2);
Run Code Online (Sandbox Code Playgroud)
然后可以访问具有以下类型的函数指针:
FooType1* (*)(A);
FooType1* (*)(B);
FooType2* (*)(A);
FooType2* (*)(B);
Run Code Online (Sandbox Code Playgroud)
我知道我可以MAKE_FOO_FNS用模板替换:
template<typename FooType>
FooType* makeFooA(A arg) {
return new FooType(arg);
}
// .. etc ..
Run Code Online (Sandbox Code Playgroud)
这样我们就可以得到函数指针&MakeFooA<FooType1>,&MakeFooA<FooType2>等等,无任何宏观两轮牛车.
但是,这仍然似乎是不必要的样板---有没有(C++ 11)的方式来得到一个函数指针直接向"调用运营商new的FooType1与需要一个构造函数 …
我正在从虚拟表中的地址调用虚函数作为练习,以测试我对该概念的理解.但是,一旦我认为我在理解虚拟方法表时取得了突破,我就遇到了另一个我不明白的问题.
在下面的代码中,我创建了一个名为的类Car,它包含一个成员变量x和两个虚函数,第一个和第二个.现在,我通过黑客攻击虚拟表来调用这两个虚拟方法.第一个函数返回正确的答案,但第二个函数返回一些随机值或垃圾,而不是它初始化的内容.
#include <cstdio>
class Car
{
private:
int x;
virtual int first()
{
printf("IT WORKS!!\n");
int num = 5;
return num;
}
virtual int second()
{
printf("IT WORKS 2!!\n");
//int num = 5;
return x;
}
public:
Car(){
x = 2;
}
};
int main()
{
Car car;
void* carPtr = &car;
long **mVtable =(long **)(carPtr);
printf("VTable: %p\n", *mVtable);
printf("First Entry of VTable: %p\n", (void*) mVtable[0][0]);
printf("Second Entry of VTable: %p\n", (void*) mVtable[0][1]);
if(sizeof(void*) == 8){
printf("64 …Run Code Online (Sandbox Code Playgroud) c++ virtual-functions member-function-pointers c++14 virtual-table
有没有办法确定成员函数指针的返回类型?
代码示例:
///// my library
void my_func(auto mptr) { // have to use `auto`
// some logic based on a return type of mptr: int, string, A, etc.
}
///// client code
struct A {
int foo();
std::string bar(int);
};
class B{
public:
A func(int, double);
};
// ... and many other classes
my_func(&A::foo);
my_func(&A::bar);
my_func(&B::func);
// ... many other calls of my_func()
Run Code Online (Sandbox Code Playgroud)
我需要“填写” my_func()。
编辑:我不能使用std::result_of/std::invoke_result因为我不知道mptr. 应该使用哪些参数调用方法并不重要,因为我没有调用它。我想避免创建基类的对象,mptr即使我能够确定它(使用declval是可以的)。
我想知道为什么该语言允许声明指向成员函数/数据的指针,尽管该成员类型不存在,而且我们知道在编译时,必须知道静态类型,并且在使用之前必须知道类型必须是完整类型除了在如此受限制的情况下使用不完整的类型。
这是我的例子:
struct Foo{
int bar(bool, bool){std::cout << "Foo::bar\n"; return x_;}
int x_ = 10;
void do_it()const{cout << "do_it()\n";}
void do_it(int, bool)const{cout << "do_it(int, bool)\n";};
};
int main(){
int (Foo::* pMemBar)(bool, bool) = &Foo::bar; // ok
(Foo{}.*pMemBar)(0, 0); // ok
int Foo::*pMemX = &Foo::x_;
std::cout << Foo{}.*pMemX << '\n';
std::string (Foo::* pMemFn)(char)const; // why this is allowed?
std::string Foo::* pMemDt = nullptr; // why allowed
}
Run Code Online (Sandbox Code Playgroud)
pMemFn,该指针是指向类的成员函数Foo即const与只有一个参数作为char并返回std::string。但是类中没有这样的版本,Foo正如我们所知,编译器确实知道类的所有成员,那么为什么它允许呢?我知道这个指针还没有被取消引用,因此在这样的声明中没有那个类的对象,编译器只有在使用那种类型的对象取消引用它时才会抱怨,class …如果我有一个重载的非静态成员函数,我如何auto为该函数的一个版本声明一个指针?
struct Foo{
void bar(){}
void bar(int){}
};
auto ptr = &Foo::bar; // error: unable to deduce 'auto' from '&Foo::bar'
Run Code Online (Sandbox Code Playgroud) 当我根据某些条件获得指向成员函数的指针然后调用该函数时,我有以下类。
class Test
{
public:
bool isChar(char ch) { return (ch >= 'a' && ch <= 'z'); }
bool isNumeric(char ch) { return (ch >= '0' && ch <= '0'); }
enum class TestType
{
Undefined,
Char,
Numeric,
AnotherOne,
};
bool TestFor(TestType type, char ch)
{
typedef bool (Test::*fptr)(char);
fptr f = nullptr;
switch(type)
{
case TestType::Char:
f = &Test::isChar;
break;
case TestType::Numeric:
f = &Test::isNumeric;
break;
default: break;
}
if(f != nullptr)
{
return (this->*f)(ch);
}
return false;
} …Run Code Online (Sandbox Code Playgroud) PiGPIO库提供以下C风格的API函数:
typedef void (*gpioAlertFuncEx_t)(int, int, uint32_t, void *); // assumed
int gpioSetAlertFuncEx(unsigned user_gpio, gpioAlertFuncEx_t f, void *userdata)
Run Code Online (Sandbox Code Playgroud)
基本上它允许您通过回调函数处理引脚状态更改.
到现在为止还挺好.问题是将此回调包装到c ++类中.
我的方法如下:
class Pin
{
public:
Pin(_GpioPin)
{
gpioSetAlertFuncEx(_GpioPin, &PushButton::internal_gpio_callback, this );
}
void internal_callback_func(int pin, int level, uint32_t tick)
{
cout << "New level: " << pin << " " << level;
}
}
Run Code Online (Sandbox Code Playgroud)
问题是回调函数类型不同(因为它是非静态的).并且提示错误:
error: cannot convert 'void (Pin::*)(int, int, uint32_t, void*) {aka void (Pin::*)(int, int, unsigned int, void*)}' to 'gpioAlertFuncEx_t {aka void (*)(int, int, unsigned int, void*)}' for …Run Code Online (Sandbox Code Playgroud)