2017-11-25 82 views
0

嗨,大家好,也許你能幫助我在此,如何確定通過向量與模板函數的類型

我有兩個向量(vecInt,vecDouble)。很明顯,一個是int類型,另一個是雙重類型。

但是,如何檢查if和else中的那些向量的類型?

if (TYPE OF VECTOR == INT) { 
     std::cout << "vecInt: "; 
    } 
    else if (TYPE OF VECTOR == DOUBLE) { 
     std::cout << "vecDouble: "; 
    } 
+1

模板的重點在於避免必須知道類型。你可以不打印矢量類型* *在調用模板函數之前,你仍然知道類型? – Galik

+0

的確如此。我現在正在做這件事,現在我意識到模板功能絕對不是正確的地方。我將編輯我的問題到更一般的方法。 – Kai

+0

你的編輯不會改變這個問題,它只是讓我的答案看起來像我憑空製作的東西。 – StoryTeller

回答

4

但是我怎麼檢查這些類型的載體中,如果和其他人如果?

你不知道。這並不是說你不能,只有你不應該。這種分支不會給你想要的解決方案,10次中的9次。優越的選擇是超載。不要添加分支,而是添加一個輔助函數的調用,然後重載,以獲得所需的行爲。

它應該是這樣的:

#include <vector> 
#include <iostream> 

template<typename T> 
void output_helper(std::vector<T>*) {} 

void output_helper(std::vector<int>*) { 
    std::cout << "vecInt: "; 
} 

void output_helper(std::vector<double>*) { 
    std::cout << "vecDouble: "; 
} 

template <typename T> 
void output(std::vector<T>* vO) { 
    output_helper(vO); 

    for (size_t i = 0; i < vO->size(); i++) { 
     std::cout << (*vO).at(i) << " "; 
    } 
    std::cout << std::endl; 
} 

int main() { 
    std::vector<int> v{1, 2, 3}; 
    output(&v); 
    return 0; 
} 

這的確輸出

vecInt: 1 2 3 

正如你可以看到live。超載的主要好處是可以在不修改它的情況下擴展output的行爲。只需爲另一個矢量類型添加一個過載。

順便說一句,考慮用指針開關傳遞,並通過引用傳遞,就像在慣用的C++中一樣。

+0

謝謝你的解決方案!請不要因爲編輯我的問題而生氣。爲什麼在模板中做這樣的事情是「壞事」? – Kai

+0

@凱 - 我沒有生氣,我只是預見了一大堆評論,這些評論問我我在哪裏提出了關於指點的建議。無論如何..我沒有說這是壞的。只有這可能不是你想要的。在特定的**類型上自定義模板在分支鏈中完成時不穩健。過載設置很容易擴展,沒有分支可見。編譯好的函數「只是做它應該做的事」而不做任何檢查。 – StoryTeller

+0

我可能會使用'output_helper'的模板特化,並且只是通過'T'而不是實際的'vector'指針。在'for'循環中使用'at()'會浪費開銷,因爲循環已經在執行自己的範圍檢查。使用'運算符[]',或者更好的迭代器,或者甚至是[range-for循環](http://en.cppreference.com/w/cpp/language/range-for) –

3

您可以使用型性狀的C++ 11和C++ 14:

#include <type_traits> 

if (std::is_same<T, int>::value) { 
    std::cout << "vecInt: "; 
} 
else if (std::is_same<T, double>::value) { 
    std::cout << "vecDouble: "; 
} 

注意,這是一個運行時檢查,但是編譯器應該能夠優化它拿走。

在C++ 17,你可以改用if constexpr,這使它成爲一個保證編譯時檢查沒有運行時開銷,而你也可以使用_vis_same爲了不必每次都寫::value

if constexpr (std::is_same_v<T, int>) { 
    std::cout << "vecInt: "; 
} 
else if constexpr (std::is_same_v<T, double>) { 
    std::cout << "vecDouble: "; 
} 

然而在實踐中,即使是前一版本應該結束了,沒有運行時檢查,因爲編譯器將優化掉的樹枝,因爲如果條款是編譯時常量表達式。在每個模板專業化中,編譯器都可以看到其中一個分支永遠不會被佔用,因此會刪除該分支。

+0

「請注意,這是一個運行時檢查「。 →通常,它會被優化。 – Constructor

+0

@Constructor是的,雖然不能保證。我沒有檢查它。 –

+0

我的意思是,實際上'if'和'如果constexpr'在這種情況下的區別不是編譯時和運行時檢查條件之間的區別。簡單的'if'需要儘管條件成功編譯兩個分支。 '如果constexpr'沒有這樣的要求,所以這個功能在編寫模板代碼時非常有用。 – Constructor

相關問題