如何在构造函数中限制字符数组长度
How to limit char array length in constructor
使用扩展嵌入式 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,因为平台不支持它。
你基本上有两个解决方案:SFINAE (C++98) or static_assert
(C++11):
SFINAE
您只能为小于给定大小 long 的字符数组提供 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."
}
可能最简单的方法是添加 static_assert
,如果您的实现还没有 static_assert
,则使用 the old C techniques for compile-time checks 之一:
#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.
}
使用扩展嵌入式 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,因为平台不支持它。
你基本上有两个解决方案:SFINAE (C++98) or static_assert
(C++11):
SFINAE
您只能为小于给定大小 long 的字符数组提供 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."
}
可能最简单的方法是添加 static_assert
,如果您的实现还没有 static_assert
,则使用 the old C techniques for compile-time checks 之一:
#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.
}