Как ограничить длину массива символов в конструкторе - PullRequest
0 голосов
/ 30 ноября 2018

Использование Extended Embedded 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 ++ не 'Я не уверен, если это вообще возможно.

Я ищу какой-нибудь способ, чтобы шаблон привел к хорошей ошибке компиляции.К сожалению, я не могу использовать повышение, так как платформа не будет поддерживать его.

Ответы [ 2 ]

0 голосов
/ 30 ноября 2018

Вероятно, самый простой способ - добавить static_assert, используя один из старых методов C для проверок во время компиляции , если ваша реализация еще не имеет 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.
}
0 голосов
/ 30 ноября 2018

У вас есть два основных решения: SFINAE (C ++ 98) или static_assert (C ++ 11):

SFINAE

Вы можете предоставить конструктор для 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
}

Живая демоверсия

Утверждение (только C ++ 11)

Внутри конструктора Param вы можете проверить , если поставляемый массив символов слишком большой и выдать читаемую ошибку во время компиляции:

#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демо

...