char 指针的模板特化?
boost::lexical_cast
是一个很棒的工具,但在我的应用程序中,我遇到了 string ->; 的限制。 bool
转换困扰着我。我需要将 "0"
、"false"
和 "FALSE"
等所有字符串转换为 false
和 <将 code>"1"、"true"
和 "TRUE"
转换为 true
。
boost::lexical_cast
仅支持 "0"
和 "1"
之间的转换。所以我的想法是编写我自己的转换函数,它似乎工作得很好:
bool str_to_bool(const std::string &str)
{
if(str == "1" || str == "true" || str == "TRUE")
return true;
else if(str == "0" || str == "false" || str == "FALSE")
return false;
else
throw std::runtime_error("Bad cast from std::string to bool!");
}
现在我想编写一个围绕 boost::lexical_cast
的包装器并为其编写我自己的模板专业化。这是我到目前为止所得到的:
template<typename Target, typename Source>
inline Target my_cast(const Source& src)
{
return boost::lexical_cast<Target>(src);
}
template<>
inline bool my_cast(const std::string& src)
{
return str_to_bool(src);
}
这对于整数或 std::string 非常有效,但对于字符串文字或字符指针显然失败:
int main(int argc, char* argv[])
{
std::cout << my_cast<bool>(1) << std::endl; //OK
std::cout << my_cast<bool>(std::string("true")) << std::endl; //OK
std::cout << my_cast<bool>("true") << std::endl; //Fail!
return 0;
}
所以我尝试为 char *
编写另一个专门化,但它失败了编译!
//does not compile!
template<>
inline bool my_cast(const char*& src)
{
return str_to_bool(src);
}
支持 std::string 和 char * 的正确方法是什么?
编辑1:标题很愚蠢。修好了。
编辑2:我借用了boost本身的解决方案。作为新答案发布。
boost::lexical_cast
is a great tool but in my application I ran into a limitation in string -> bool
conversion that is bugging me. I need to convert all strings like "0"
, "false"
and "FALSE"
into false
and "1"
, "true"
and "TRUE"
into true
.
boost::lexical_cast
only support conversion from/to "0"
and "1"
. So my idea was to write my own conversion function which seems to work fine:
bool str_to_bool(const std::string &str)
{
if(str == "1" || str == "true" || str == "TRUE")
return true;
else if(str == "0" || str == "false" || str == "FALSE")
return false;
else
throw std::runtime_error("Bad cast from std::string to bool!");
}
Now I wan to write a wrapper round boost::lexical_cast
and write my own template specializations for it. Here is what I've got so far:
template<typename Target, typename Source>
inline Target my_cast(const Source& src)
{
return boost::lexical_cast<Target>(src);
}
template<>
inline bool my_cast(const std::string& src)
{
return str_to_bool(src);
}
This works great for integers or std::string but obviously fails for string literals or character pointers:
int main(int argc, char* argv[])
{
std::cout << my_cast<bool>(1) << std::endl; //OK
std::cout << my_cast<bool>(std::string("true")) << std::endl; //OK
std::cout << my_cast<bool>("true") << std::endl; //Fail!
return 0;
}
So I tried to write another specialization for char *
but it fails to compile!
//does not compile!
template<>
inline bool my_cast(const char*& src)
{
return str_to_bool(src);
}
What is the correct way to support both std::string and char *
?
EDIT 1: the title was stupid. Fixed it.
EDIT 2: I borrowed a solution from boost itself. Posted as a new answer.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是一个有效的解决方案。我从 boost::lexical_cast 本身得到了这个想法:
主要的挑战是处理数组类型。 array_to_pointer_decay 将任何数组类型转换为相应的指针类型。现在剩下的就很容易了。
Here is a solution that works. I got the idea from
boost::lexical_cast
itself:The main challenge is to deal with array types. The
array_to_pointer_decay
converts any array type to the corresponding pointer type. The rest is easy now.您需要使用
const char*
,而不是const char*&
。这里的可变左值引用只会绑定到左值,而字符串文字实际所在的数组类型的衰减只会产生右值const char*
,您只能将 const 引用绑定到该右值。You need to take a
const char*
, not aconst char*&
. The mutable lvalue reference here will only bind to an lvalue, whereas the decay from the array type that the string literal actually is will only produce an rvalueconst char*
, to which you can only bind a const reference.让我将其添加为新答案......打字擦除版本!
对于 C++98/03
类型特征版本,模板化返回类型
Let me add this as a new answer... a type-erasing version!
For C++98/03
Type-traited version, templated return type
如果你这样说:
那么至少你可以进行以下工作:
更新:瞧:
If you say this:
Then at least you can make the following work:
Update: Voila: