簡體   English   中英

C++ 自動推導返回類型

[英]C++ auto deduction of return type

我想編寫一個基於不同輸入返回不同類型的函數,如下所示。

enum MyType
{
    A,
    B
};

template<MyType T> struct MyStruct
{

};

static auto createMyStruct(MyType t)
{
    if(t==A)
        return MyStruct<A>();
    else
        return MyStruct<B>();
}

它沒有成功,因為一輛汽車有兩種返回類型。 有沒有其他方法可以做到這一點?

絕對沒有辦法讓(單個)函數根據運行時決定返回不同的類型。 必須在編譯時知道返回類型。 但是,您可以像這樣使用模板函數(感謝@dyp 讓我簡化了代碼):

#include <iostream>
#include <typeinfo>

enum MyType
{
    A,
    B
};

template<MyType>
struct MyStruct {};

template<MyType type>
MyStruct<type> createMyStruct()
{
    return {};
}

int main()
{
    auto structA = createMyStruct<A>();
    auto structB = createMyStruct<B>();

    std::cout << typeid(structA).name() << std::endl;
    std::cout << typeid(structB).name() << std::endl;
}

我認為你應該學習抽象工廠設計模式

要使用MyStruct<A>MyStruct<B>類型的對象,您需要通用接口。

抽象基類中提供的通用接口。

struct MyStruct
{
    virtual ~MyStruct() {}
    virtual void StructMethod() = 0;
};

struct MyStructA: public MyStruct
{
    void StructMethod() override {}
};

struct MyStructB: public MyStruct
{
    void StructMethod() override {}
};

std::unique_ptr<MyStruct> createMyStruct(MyType t)
{
    if (t==A)
        return std::make_unique<MyStructA>();
    else
        return std::make_unique<MyStructB>();
}

我假設你想寫這樣的代碼:

void foo (MyType t) {
    auto x = createMyStruct(t);
    //... do something with x
}

您正在嘗試在運行時為x派生正確的類型。 但是,函數的返回類型必須在編譯時知道,而auto的類型解析也在編譯時確定。

您可以改為將代碼重構為如下所示:

template<MyType T> struct MyStruct
{
    //...
    static void foo () {
        MyStruct x;
        //... do something with x
    }
};

這個想法是編寫一個foo()函數,它的唯一區別是它所操作的東西的類型。 這個函數被封裝在類型本身中。 如果您有MyTypeMyStruct<MyType>::foo之間的映射,您現在可以做出運行時決策。

typedef std::map<MyType, void(*)()> MyMap;

template <MyType...> struct PopulateMyMap;

template <MyType T> struct PopulateMyMap<T> {
    void operator () (MyMap &m) {
        m[T] = MyStruct<T>::foo;
    }
};

template <MyType T, MyType... Rest> struct PopulateMyMap<T, Rest...> {
    void operator () (MyMap &m) {
        m[T] = MyStruct<T>::foo;
        PopulateMyMap<Rest...>()(m);
    }
};

template<MyType... Types> void populateMyMap (MyMap &m) {
    PopulateMyMap<Types...>()(m);
}

//...
    populateMyMap<A, B>(myMapInstance);

然后,做出運行時決策:

void foo (MyType t) {
    myMapInstance.at(t)();
}

暫無
暫無

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

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