2017-08-09 56 views
1

我希望創建一個與許多類型的作品一類。 然而,我想實例化這個類的一個元素不是一個類型,而是一個字符串(例如使用"int"代替int),使我沒有使用這個類時做出廣泛的調度功能。模板用字符串,而不是類型

在一個小班Tab,我嘗試了兩種 「解決方案」:

第一招:

template <typename T> 
class Tab { 
public : 

    Tab(std::size_t length) { 
    T* tab_[length]; 
    tab = tab_; 
    } 

    T* tab; 

    T operator[](std::size_t i) { 
    return tab[i]; 
    } 
}; 

Tab getTab(std::string type, std::size_t length) { 

    if (type == "int") { 
     Tab<int> tab(length); 
    } else if (type == "double") { 
     Tab<double> tab(length); 
    } 

    return tab; 
} 

第二個:

typedef boost::variant<int, double> numeric; 
typedef boost::variant<int*, double*> numeric_ptr; 

class Tab { 
public : 

    Tab(std::string type, std::size_t length) { 
    if (type == "int") { 
     tab = new int[length]; 
    } else if (type == "double") { 
     tab = new double[length]; 
    } 
    } 

    numeric_ptr tab; 

    numeric operator[](std::size_t i) { 
    return tab[i]; 
    } 
}; 

兩個嘗試不進行編譯。我很樂意爲我的問題提供一個不那麼複雜的解決方案。

編輯:你爲什麼要使用字符串代替typenames擺在首位?

我有一個用一個模板類的許多功能。在每個函數中,我都可以將模板類的類型名稱作爲字符串來知道,因此我必須使用像這樣的調度函數:https://github.com/privefl/bigstatsr/blob/master/src/colstats.cpp。如果你有20個這樣的函數,爲它們中的每一個寫一個調度函數真的很煩人(並且容易出錯)。

所以我寧願喜歡的類的實例只創建一個調度功能,並在需要這個模板類的一個實例的所有功能,使用該功能。

+1

爲什麼不讓'getTab'成爲函數模板? – 0x499602D2

+0

@ scohe001編輯:不編譯。 –

+0

@ 0x499602D2正是我想避免的。我想模板,但用字符串。 –

回答

5

你可以這樣做:

template <typename T> 
class Tab { 
public: 
    Tab(std::size_t length) : tab(length) {} 

    // ... 
private: 
    std::vector<T> tab; 
}; 

boost::variant<Tab<int>, Tab<double> > 
CreateTab(const std::string& type, std::size_t length) 
{ 
    if (type == "int") { 
     return Tab<int>(length); 
    } else if (type == "double") { 
     return Tab<double>(length); 
    } 
    throw std::runtime_error("Bad type"); 
} 
+0

看起來很有希望。我會明天嘗試你的解決方案並回到你身邊。 –

+0

**似乎我不能使用'boost :: variant ,Tab >'作爲Tab類的一個元素**編譯器說'boost :: variant ,Tab >'不會有'Tab'類的成員和方法。 –

2

我不會「模板上串」和返回類型返回一個變種,而是模板。然後,您可以

getTab<int>(17); 

即使這樣,你不需要任何「昂貴的調度功能,」你在你的問題中提到。你剛纔模板在包裝類型的Tab爲使

template < typename T > 
void algorithm(Tab<T> const& t) { ... } 

我也替換爲std::vector裸指針,易於使用和記憶的正確性。

#include <vector> 

template <typename T> 
class Tab { 
    std::vector<T> tab; 
public : 

    Tab(std::size_t length) : tab(length) {} 

    T operator[](std::size_t i) { 
    return tab[i]; 
    } 
}; 

template < typename T > 
Tab<T> getTab(std::size_t length) 
{ 
    return Tab<T>(length); 
} 

int main() 
{ 
    auto ti = getTab<int>(17); 
    auto td = getTab<double>(29); 
} 
+0

我不明白這是如何防止我不得不將字符串分配給typenames? –

+0

@F.Privé爲什麼你首先使用字符串而不是typenames?在這個例子中顯然沒有必要。 –

+0

公平的問題。看我的編輯。 –

相關問題