2017-05-11 26 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