2013-09-21 70 views
3

我期待寫一個char BUF包裝,保證空終止類似如下:找出數組長度靜態地使用模板在C++

template<size_t N> class BufStr 
{ 
public: 
    explicit BufStr(const char(&buf)[N]) 
    { 
     memcpy(m_buf, buf, N); 
     m_buf[N-1] = '\0'; 
    } 

    inline const char* c_str() const { return m_buf; } 

protected: 
    char m_buf[N]; 
}; 

但我想使用的簽名模板,並能夠將char buf直接傳遞給構造函數,該構造函數可以使用sizeof來確定數組的大小,因此可以在編譯時計算N。

+0

如果你說'MakeBufStr(「Hello」)',那已經包含一個空終止符,對嗎? –

+0

這是一個函數來轉換一個非空終止的char buf如char buf [10]爲空終止 – stgtscc

+0

當然,標準的「類模板加推導make功能」成語。你剛剛得到一個解釋這個答案。 –

回答

2

編輯要考慮要「包」非零結尾的字符數組的事實:

你可以有一個「工廠」功能:

template <size_t N> 
    BufStr<N+1> make_bufstr(const char(&buf)[N]) 
{ 
    return BufStr<N+1>(buf); 
} 

演示(注使用的std::copy代替memcpy):

#include <cstdint> 
#include <algorithm> 

template<std::size_t N> class BufStr 
{ 
public: 
    explicit BufStr(const char(&buf)[N-1]) 
    { 
     static_assert(N>0, "illegal size"); 
     std::copy(buf, buf+N-1, m_buf); 
     m_buf[N-1] = '\0'; 
    } 

    inline const char* c_str() const { return m_buf; } 

protected: 
    char m_buf[N]; 
}; 

template <size_t N> 
    BufStr<N+1> make_bufstr(const char(&buf)[N]) 
{ 
    return BufStr<N+1>(buf); 
} 

int main() 
{ 
    const char raw[] = { 'H', 'e', 'l', 'l', 'o' }; // no NUL termination! 
    auto s = make_bufstr(raw); // adds terminating NUL 
} 
+0

啊,我誤解了,並沒有意識到這是絆腳石。是的,「Hello world」的例子似乎完全是*不是*想要的。 –

+0

@KerrekSB我忍者編輯:) – sehe

+0

盛大。我仍然不確定這樣的功能是否有用。更好地說'std :: string(std :: begin(raw),std :: end(raw)'並且得到完全相同的功能。 –

0

試試這個:

template <typename T> 
using buf_type = BufStr<::std::extent<T, 0>{}>; 

int main() 
{ 
    char bla[] = "heh"; 

    buf_type<decltype(bla)> buf(bla); 

    return 0; 
}