3

我正在寻找一个 char buf 包装器来保证空终止,如下所示:

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 。

4

2 回答 2

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
}
于 2013-09-21T21:54:14.377 回答
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;
}
于 2013-09-21T22:39:04.363 回答