簡體   English   中英

在運行時設置矢量類型

[英]Set vector type at runtime

我有一個程序,需要在程序執行時設置向量的類型(根據配置文件中的值)。

我試過這個:

int a = 1

if(a == 1)  vector<int> test(6);
else  vector<unsigned int> test(6);

test.push_back(3);

但這給了我:

Error   1   error C2065: 'test' : undeclared identifier

我不完全確定原因,但我認為這是因為矢量實際上並不是在編譯時決定的,因此編譯器在編譯其余代碼時無法使用它。

有沒有辦法在運行時決定向量的類型,類似於我上面嘗試的? 我試圖在if之外創建一個版本然后刪除它並在IF中重新編寫新版本。 然而這感覺不對,無論如何我無法讓它工作。 謝謝。

它不起作用的原因是你分別在if-和else-block中聲明了向量,因此一旦該塊結束它們就會超出范圍。

有沒有辦法在運行時決定向量的類型,類似於我上面嘗試的?

不,必須在編譯時知道變量的類型。 您唯一的選擇是將test.push_back(3)行以及任何訪問test以下代碼放入if-和else-block,或者避免代碼復制到第二個模板化函數中。 這看起來像這樣:

template <class T>
do_something_with_test(vector<T>& test) {
    test.push_back(3);
    // work with test
}

void foo() {
    int a = 1

    if(a == 1) {
        vector<int> test(6);
        do_something_with_test(test);
    }
    else {
        vector<unsigned int> test(6);
        do_something_with_test(test);
    }
}

您獲得錯誤的確切原因對於初學者來說是一種微妙的原因,它涉及您正在創建的變量test的范圍。 簡單地說,您正在if語句中創建向量,但是當您要使用它時,它不再存在,因為它已超出范圍。

我用括號重新格式化了你的代碼,使這個效果更加明顯。 請注意,我的版本在語義上與您的版本等效,並且會出現相同的錯誤。

if(a == 1)
{
  vector<int> test(6);
}
else
{
  vector<unsigned int> test(6);
}

test.push_back(3);

那就是說,你想要做的事情看起來有點奇怪,我不得不想知道你的最終目標是什么。 這並不是說沒有辦法去做你似乎想要做的事情,但在我建議一個更合適的方法之前,我需要知道你的成功標准。

我不確定你為什么需要這個,但我建議你嘗試使用聯合矢量來解決你的問題,就像這樣

union DataType
{
    int intVal;
    unsigned uintVal;
}
std::vector<DataType> vec;

或者更優雅的方式是使用boost :: variant而不是union。 也許如果你給我們更多關於你的問題的細節你會得到更好的asnwer。

祝好運!

你可以看看boost :: any來實現類似的東西。

設置向量的類型(也稱為模板實例化 )總是在編譯時發生。 有關更多說明,請查看Wikipedia關於模板元編程的文章。

如果你真的需要一個多態類型,也許你可以看看boost :: variant類或類似的東西;
它旨在模仿C ++中動態語言的某些行為,通常用於與(或實現)它們進行交互。 你可以創建一個“vector <Variant> a”和a.push_back(Variant((unsigned int)..)。推送值的構造函數需要編譯時類型。

如果您期望值是同質的,那么還可以創建一個矢量化變體類來存儲整個集合的類型信息。

但是,如果沒有這樣的機制,你更有可能實現理想的最終結果,重新編寫你的程序以避免運行時類型檢查(這很可能會否定一開始使用C ++而不是其他語言的一些好處)。

您可以將類型相關部分編寫為模板(如上所述),並根據配置文件設置選擇一個替代代碼路徑,並將其分派一次。 使用'auto'和decltype(),這種編碼風格在c ++ 0x中稍微容易一些。

無符號與有符號值的具體情況涉及允許一個聽起來不尋常的位,或者與增加的復雜性相比具有邊際效益,但我可以很容易地想象一個想要在單精度和雙精度浮點之間切換的實現。

另一個簡單的選擇是為類型進行編譯時設置(例如,作為構建設置或makefile中的定義引入),然后分發程序的多個版本,這在某些情況下可能有意義。 但是,已建議的模板更可能是最有用的選項。

在您的示例中,您在if語句的每個分支中創建了一個變量test獨立實例,每個分支都立即超出范圍。 所以當編譯器進入test.push_back(3); 范圍內沒有test變量,因此出錯。

為了解決你的問題,你無法對抗類型系統:假設intunsigned int是有問題的實際類型,你最好總是使用vector<int> ,假設你實際上並不需要完整的unsigned int的范圍。

暫無
暫無

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

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