【问题标题】:What is the correct syntax for declaring a function pointer with generic class pointer as an argument?用泛型类指针作为参数声明函数指针的正确语法是什么?
【发布时间】:2013-08-31 10:18:10
【问题描述】:

在 MinGW 工具链中使用 C++11 开关:

我想设置一个通用事件处理程序,它将一个指针参数(引用也可以)指向我可能想要的任何类型的类。

用泛型类指针作为参数声明函数指针的正确语法是什么?

我试过了:

typedef void ( *OnChange ) ( class* );

编译器错误:

typedef ‘OnChange’ 已初始化(改用 decltype)

我对 decltype() 不熟悉,从我读到的关于它的信息来看,这不是我需要的。

我也试过了:

typedef void ( *OnChange ) ( auto* );

编译器错误:

参数声明为“自动”

我认为这意味着 auto 不能用于参数声明。

我应该如何声明 typedef? (或者也许我需要做一些不同的事情?)

【问题讨论】:

  • 这里的泛型类是什么?如果是模板化的,那么你可以使用模板的类型
  • 你会如何使用这个函数指针?
  • 这样的typedef应该放在模板structclass中,然后你可以很容易地引用模板参数。
  • 您可能正在寻找类型擦除。除非您澄清其他评论者提出的一些问题,否则我们无法确定。

标签: c++ pointers c++11 types


【解决方案1】:

C++ 是一种静态类型语言。尽管 auto 和模板之类的功能可能会让您不这么认为,但 C++ 编译器必须在编译时知道系统中所有内容的类型。 auto 和模板允许它在某些情况下推断类型,但只有当编译器肯定知道该类型是什么时。

C++ 中没有“通用类指针”这样的东西。每个指针必须是指向显式类型的指针。每个指向一种类型的指针都是与指向其他类型的指针根本不同的类型。 C++ 不认为指向不同类型的指针是可互换的(尽管它确实允许一些隐式转换,例如从指针到 void* 的转换)。

你需要的不是函数指针;指针必须具有显式类型,并且您需要保存不是显式类型的东西。你需要的是一个函子;这是因为operator() 方法可以是一个模板。但是,这将要求您将包含此函子的类设为模板(函子的类型由用户作为模板参数传入),或者您需要使您的类使用类型擦除技术,以便它可以调用用户传入和注册的任何函子值。

后者需要std::function 之类的东西,只需要一个任意的模板化operator() 函数调用,而不是一个具体的类型化函数。

【讨论】:

  • “C++ 中没有“泛型类指针”这样的东西 明白了。我对 C++ 没有那么经验。我习惯了 Object Pascal、C# 之类的语言(它们也是静态类型的)和 Python,它们有一个基础 Object Type,所有其他对象都继承自,因此您可以声明一个以“Object*”作为参数的函数,并接受任何 Object 类型作为参数。这是不像 C++ 中的 class,它不是其他类的基类型,而是声明类型的关键字。当我进一步思考时,我意识到我必须使用模板来获得我需要的东西。
【解决方案2】:

我认为你可以使用这样的东西:

template<typename T>
struct X{
 typedef void  (*OnChange)  ( T* );
};

void foo(int* ptr){
}

class Test;

int main(){
    int a=12;
    X<int>::OnChange ptr= foo;
    ptr(&a);

    X<Test>::OnChange o;
 }

【讨论】:

    【解决方案3】:

    使用语法的 C++11 编译器可以使用模板类型定义:

    template < typename T >
    using OnChange = void (*)( T * ); 
    

    【讨论】:

    • 你不能声明任何OnChange类型的指针,因为它根本不是一个type;这是一个模板。技术上是模板别名,但同样的东西。
    猜你喜欢
    • 2010-09-18
    • 1970-01-01
    • 2018-05-18
    • 1970-01-01
    • 2020-09-06
    • 2011-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多