簡體   English   中英

函數指針中的協變類型

[英]covariant types in function pointers

為什么在下面的示例中強制轉換函數是錯誤的? 協變類型應該像這樣工作嗎?

#include <iostream>

struct A{};
struct B : public A{};

typedef A*(*func)();

B* b() { std::cout << "b"; return new B; }
A* a() { std::cout << "a"; return new A; }

int main(int argc, char *argv[])
{
    func fa = a;
    fa();

//  I can't do this
//  func fb = b;
//  fb();
}

即使有道理,它也不受支持。

在C ++ 11中,您可以當場輕松定義包裝器:

#include <iostream>

struct A{};
struct B : public A{};

typedef A*(*func)();

B* b() { std::cout << "b"; return new B; }
A* a() { std::cout << "a"; return new A; }

int main(int argc, char *argv[])
{
    func fa = a;
    fa();

    func fb = []() -> A* { return b(); };
    fb();
}

免責聲明:編譯器無法觸及的代碼。

考慮使用std::function而不是function指針:

#include <functional>
#include <iostream>

struct A{};
struct B : public A{};

using func = std::function<A*()>;

A* a() {std::cout << "a"; return new A;}
B* b() {std::cout << "b"; return new B;}

int main() {
    func fa = a;
    fa();

    func fb = b;
    fb();
}

演示版

僅在類的virtual成員函數的返回類型中支持協變類型。 全局功能不支持它們。

struct A
{
   virtual A* copy() {return new A();}
};

struct B : public A
{
   virtual B* copy() {return new B();}
};

void foo()
{
   B b;
   A* ap = b.copy(); // OK
   B* bp = b.copy(); // OK
   A* ap2 = ap->copy(); // OK
   B* bp2 = ap->copy(); // NOT OK
}

您可以對全局功能使用“干杯= Alf”建議的變通方法。

這就是所謂的類型轉換。 並非每個A都是B ,因此編譯器無法自動進行該轉換。 考慮這種情況:

struct A {};
struct B : public A {};
struct C : public A {};

A* a = new A; //OK
a = new B; // B is derived from A, valid
a = new C; // C is also derived from A, valid

B* b = new B; // OK
b = new C; // error, B is not derived from C 
b = new A; // error, B might have some members that A does not have

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM