2017-05-11 67 views
1

根據用戶的選擇,我必須從數據庫中導出數據,數據庫爲XMLCSV
我股票的選擇是這樣的:根據三元表達式聲明變量類型

const bool isXml = (cbxFormat->currentIndex() == 1 ? true : false); 

和寫入導出文件,我使用的是QXmlStreamWriterQTextStream
我想避免if/else聲明來聲明我的流。
我已經嘗試使用decltype這樣的:

decltype((isXml ? QXmlStreamWriter() : QTextStream())) stream; 

但我不能因爲QXmlStreamWriterQTextStream沒有相同的基類,並在基類的情況是一樣的,stream類型是「最寬」的類型。

我還試圖用std::conditional但我不能,因爲isXml在運行時被稱爲:

std::conditional<isXml, QXmlStreamWriter, QTextStream>::type stream; 

是它存在一個可能的解決方案做到這一點?

QFile expFile(fileName); 
if (expFile.open(QIODevice::WriteOnly)) { 
    /* not possible */ 
    // decltype((isXml ? QXmlStreamWriter() : QTextStream())) stream; 
    /* isXml is known at runtime */ 
    // std::conditional<isXml, QXmlStreamWriter, QTextStream>::type stream(&expFile); 
    // If not possible... if/else 

    // filling my stream.. 

    expFile.close(); 
} 

回答

4

您可以編寫具有類型作爲模板參數的函數,並使用具有相應類型調用該函數的if

template <typename StreamT> 
void do_work(QFile& file) { 
    StreamT stream; 
    // ... 
    stream << strData; 
} 

void work() { 
    QFile file(file_name); 
    // ... 
    if (isXml) { 
    do_work<QXmlStreamWriter>(file); 
    } else { 
    do_work<QTextStream>(file); 
    } 
} 

編輯:

另一種解決辦法是要包裝你的流類:

struct stream_base { 
    virtual void work(QFile&) = 0; 
}; 
struct xml_stream: stream_base { 
    virtual void work(QFile&) { QXmlStreamWriter stream; ... } 
}; 
struct text_stream: stream_base { 
    virtual void work(QFile&) { QTextStream stream; ... } 
}; 
std::unique_ptr<stream_base> make_stream(bool isXml) { 
    return isXml ? std::make_unique<xml_stream>() : std::make_unique<text_stream>(); 
} 

void work() { 
    QFile file (file_name); 
    // ... 
    auto stream = make_stream(isXml); 
    stream->work(file); 
} 
+0

是的,這是一種可能性,但真的沒有辦法根據另一個變量的值聲明一個聲明嗎? –

+2

@ThibautB。您不能根據運行時已知的變量來選擇類型,因爲該類型是在編譯時推導出來的。你可以寫一個封裝你的流的類;我編輯了我的答案以添加示例。 – piwi

+1

你可以結合兩個:有一個'template struct stream_impl:stream_base ...' – Caleth