如何在构造函数中限制char数组的长度

时间:2018-11-30 10:52:28

标签: c++ templates c++98

使用扩展嵌入式Cpp。如何在发布版本中导致编译错误:

Param okParam("Yeah!"); // this line should be ok
Param nOkParam("REEEEEEEEEEE"); // too big array, not ok. compiler error.

其中:

int const c_max = 10;

template<int N>
struct Param
{
  char value[c_max];

  Param(char const (&p_value)[N])
  {
     memcpy(value, p_value, sizeof(p_value));
  }
};

我认为您无法对构造函数进行模板化,因此需要对整个结构进行模板化,对吧?


我希望它提供一个干净的编译器错误,以便使用此错误的人将立即注意到它。

我们的扩展嵌入式C ++版本不提供任何stl容器,我不确定是否可能。

我正在寻找使模板产生良好编译错误的方法。可悲的是我也不能使用boost,因为该平台将不支持它。

2 个答案:

答案 0 :(得分:4)

您基本上有两种解决方案:SFINAE(C ++ 98)或static_assert(C ++ 11):

SFINAE

您只能为长度小于给定大小的char数组提供Param的构造函数。在C ++ 98中,这看起来有点丑陋,但是可以正常工作:

#include <cstddef>

template<bool b>
struct enable_if {};

template<>
struct enable_if<true>
{
    typedef int type;
};


template<std::size_t MAXSIZE>
struct Param
{
    template<std::size_t SIZE>
    explicit Param(
        char const (&input) [SIZE],
        std::size_t = sizeof(typename enable_if<SIZE < MAXSIZE>::type) // SFINAE at work
    ) { (void) input; }
};

int main()
{
    // "hello": char const[6], 6 < 7, OK
    Param<7> p1("hello");

    // "hello world": char const[12], 12 >= 7, KO
    Param<7> p2("hello world"); // ugly error here
}

Live demo

声明(仅C ++ 11)

Param的构造函数中,您可以检查是否提供的char数组太大,并在编译时弹出可读错误:

#include <cstddef>
#include <type_traits>

template<std::size_t MAXSIZE>
struct Param
{
    template<std::size_t SIZE>
    explicit Param(char const (&input) [SIZE])
    { static_assert(sizeof(input) < MAXSIZE, "input is too big."); }
};

int main()
{
    // "hello": char const[6], 6 < 7, OK
    Param<7> p1("hello");

    // "hello world": char const[12], 12 >= 7, KO
    Param<7> p2("hello world"); // "error: static assertion failed: input is too big."
}

Live demo

答案 1 :(得分:3)

如果您的实现尚没有static_assert,可能最简单的方法是使用the old C techniques for compile-time checks中的一个添加static_assert

#include <cstring>

#if __cplusplus < 201103L
#define static_assert(expr, message)                                    \
    int static_assert_(int (&static_assert_failed)[(expr)?1:-1])
#endif

template<int N>
struct Param
{
    static const int c_max = 10;
    static_assert(N < c_max, "Param string too long");
    char value[c_max];

    Param(char const (&p_value)[N])
    {
        std::memcpy(value, p_value, sizeof p_value);
    }
};

int main()
{
    Param okParam("Yeah!"); // this line should be ok
    Param nOkParam("REEEEEEEEEEE"); // too big array, not ok. compiler error.
}