2017-07-24 63 views
0

我有一個類,我使用字符串的長度作爲模板參數。這樣,文字的長度將在編譯時進行評估,並且在運行時沒有理由執行strlen(或等效)。我想對字符串文字進行同樣的處理。存儲數組的字符串,傳遞給期望字符串的模板

// Handler class 
class Handler { 
    template<size_t N> 
    bool String(const char(&str)[N]) { /* ... */ } 
}; 

Handler myHandler; 

// Works 
myHandler.String("it"); 

// Handler::String(const char (&)[N])': could not deduce template argument for 'const char (&)[N]' from 'const char *const *' 
const char* manyIts[3] = {"this", "and", "that" }; 
for (int i = 0; i < 3; ++i) { 
    myHandler.String(manyIts[i]); 
} 

我明白,其實字符串字面量在const char*陣列存放時丟失。有沒有其他方便的方法來存儲這些以允許這種功能?

回答

1

問題是數組必須具有統一類型的元素。由於您在類型中對字符串的大小進行編碼,因此不能有不同長度的字符串數組。您可以使用std::tuple生成不同類型元素的編譯時數組。技巧是防止字符數組腐朽爲指向第一個元素的指針。

使用可變參數模板,可以編寫一個函數,返回指向const char數組的指針元組。

#include <tuple> 

// Define an alias for pointer to const char array 
template<size_t N> 
struct t_str_ptr { using type = const char(*)[N]; }; 

// Returns a tuple of pointers to cont char arrays 
template<size_t ... N> 
auto make_str_tuple(const char(&...p_str)[N]) 
{ 
    return std::make_tuple<typename t_str_ptr<N>::type...>(&p_str...); 
} 

只需用std::make_tuple依靠參數推導將產生const char *受損失的將大小信息的std::tuple

的使用變爲:

int main() 
{ 
    Handler myHandler; 

    // Works 
    myHandler.String("it"); 

    // Works 
    auto manyIts = make_str_tuple("this", "and", "that"); 

    myHandler.String(*std::get<0>(manyIts)); 
    myHandler.String(*std::get<1>(manyIts)); 
    myHandler.String(*std::get<2>(manyIts)); 
} 

現在的挑戰是遍歷tuple。由於每個元素都有它自己的類型,所以它不像編寫for循環那樣容易。請注意,std::get中的索引是模板參數。爲避免重複,請參見this question重複std::tuple

相關問題