【发布时间】:2014-09-11 08:55:24
【问题描述】:
我正在尝试编写一个模板is_c_str 来测试一个类型是否是 c 风格的字符串。我需要这个来尝试编写一个 to_string 函数,如我的另一个问题所示:
Template specialization for iterators of STL containers?。
我需要区分 c_str 和其他类型的指针和迭代器,以便我可以在面值上表示第一个,并将指针/迭代器呈现为不透明的“itor”或“ptr”。代码如下:
#include <iostream>
template<class T>
struct is_c_str
: std::integral_constant<
bool,
!std::is_same<char *, typename std::remove_reference<typename std::remove_cv<T>::type>::type>::value
> {};
int main() {
auto sz = "Hello"; //Or: const char * sz = "Hello";
int i;
double d;
std::cout << is_c_str<decltype(sz)>::value << ", "
<< is_c_str<decltype(i)>::value << ", "
<< is_c_str<decltype(d)>::value << std::endl;
}
但是,is_c_str 不仅捕获 const char *,还捕获 int 和 double。以上代码输出:
1, 1, 1
(从 gcc-4.8.1 开始)。
我的问题是如何修复 is_c_str 以正确捕获 c 风格的字符串?
【问题讨论】:
-
remove_reference<remove_cv<int>>和char *不一样吗?为什么是的,这是真的。 -
为什么需要这个?也许有一种更简单的方法可以解决您原来的问题。
-
请注意
char*只是指向char的指针。它不是 C 风格的字符串,除非它指向一个以 null 结尾的数组。 -
请注意,
wchar_t、char16_t和char32_t也可以用于 C 风格的字符串。 -
对于您的特定用例,我只需添加
template<class T> to_string(T * str);的重载并将 SFINAE 输出,除非std::decay_t<T>是char、wchar_t、char16_t和 @987654342 之一@.
标签: c++ templates c++11 typetraits