我有自己的类型
namespace FaF
{
// Allocator is my own Memory Allocator for STL
using string = std::basic_string<char, std::char_traits<char>, Allocator<char>>;
}
FaF::string number("1234");
stoi( (const std::string &) number); <-- error
使用stoi(number) aka FaF::string&
时,使用gcc
运行-Wall -Werror -Wextra
会导致此错误:
错误:解除引用类型惩罚指针将破坏严格别名 规则[-Werror = strict-aliasing]
我尝试了很多铸件,但没有任何帮助。或多或少std::string
和FaF::string
与内存分配器中的相同 。
我的问题:如何使用stoi()/stof()
函数解决此问题?
更新:: 是的,当然,我可以使用atoi( number.c_str() )
,但我想了解此处的问题。
答案 0 :(得分:2)
这是sto*
类函数的一个不幸的问题;他们仅使用std::string
。尽管他们并不关心你正在使用的分配器,但它仍然是该类型的一部分,所以它对C ++仍然很重要。你也不能假装使用不同分配器的basic_string
是std::string
。
直到C ++ 17 solves this problem (kinda),你必须手动处理它:
stoi({number.data(), number.size()});
答案 1 :(得分:1)
使用c_str
和atoi代替:
FaF::string number("1234");
int result = atoi(number.c_str()); // result == 1234
答案 2 :(得分:0)
您不能将字符串与sto *函数一起使用。如果您查看文档(http://en.cppreference.com/w/cpp/string/basic_string/stol),您会发现函数的签名完全采用std :: string。
std::string = std::basic_string<char, class Traits = std::char_traits<CharT>,
class Allocator = std::allocator<CharT>>
我想提醒您注意它使用标准分配器。所以实际上你的字符串与std :: string不同。
作为解决方法,您可以指定std :: string operator。
struct string : public std::basic_string<char, std::char_traits<char>, Allocator<char>>
{
// will produce a copy. use const char* instead
explicit operator std::string()
{
return c_str();
}
explicit operator const char*()
{
return c_str();
}
};
用法示例:
FaF::string number( "1435151315" );
std::cout << std::stoi( static_cast< std::string >( number ) );
std::cout << std::atoi( static_cast< const char* >( number ) );
PS:不要使用C风格的演员阵容! :)
我希望它有所帮助。
答案 3 :(得分:0)
在学习 std::stoi
中对basic_string.h
的定义后
inline int
stoi(const string& __str, size_t* __idx = 0, int __base = 10)
{ return __gnu_cxx::__stoa<long, int>(&std::strtol, "stoi", __str.c_str(),
__idx, __base); }
然后很容易编写我自己的 - 更通用的版本:
namespace FaF
{
template<typename T>
inline int
stoi(const T& __str, size_t* __idx = 0, int __base = 10)
{ return __gnu_cxx::__stoa<long, int>(&std::strtol, "stoi", __str.c_str(),
__idx, __base); }
}
此测试脚本
FaF::string numberFaF( "1234" );
std::string numberStd( "4321" );
printf( "stoi<FaF::string>=%d - stoi<std::string>=%d\n",
FaF::stoi( numberFaF ), FaF::stoi( numberStd ) );
编译并产生预期结果:
stoi<FaF::string>=1234 - stoi<std::string>=4321
我只是想知道为什么还没有通用版本。 STL中的几乎所有内容都是作为模板实现的,这个简单的函数是硬编码到std::string
......