2013-09-21 47 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; 
}