重载提升::lexical_cast函数
Overloaded boost::lexical_cast function
我希望编写自己的转换函数并重用boost::lexical_cast((;因此我重载了boost::lexical_cast((函数。毕竟,将 boost::conversion::try_lexical_convert(( 添加到库中也是出于同样的目的。
我的程序可以工作,重载 lexical_cast(( 在前 2 种情况下被调用,因为这两个调用都是在本地进行的。在第三种情况下,父函数 boost::lexical_cast(( 被调用,因为对 boost::lexical_cast(( 的调用是通过 parse_date(( 路由的。
我想通过我的 lexical_cast(( 函数处理所有转换,即每当调用 boost::lexical_cast(( 时,我的重载函数都会被调用。
有什么办法,我可以编写这样的全局lexical_cast((函数处理程序吗?
另外,请建议我们如何使全局处理程序自定义,以便无论何时指定,它只能为选定的少数 POD 和 boost 数据类型调用。
#include <iostream>
#include <string>
#include <exception>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
namespace boost
{
template<typename T>
T lexical_cast(const std::string &str)
{
if(str.empty()) //handle preconditions here, some custom logic
return T();
T result;
if (!conversion::try_lexical_convert(str, result))
throw bad_lexical_cast();
return result;
}
}
using namespace std;
using namespace boost;
using namespace boost::posix_time;
using namespace boost::gregorian;
int main(int ac, char* av[])
{
try
{
//1.
auto p1_ = lexical_cast<int>(std::string(""));
std::cout << "p1 = " << p1_ << std::endl; //displays 0, which is correct. calls overloaded lexical_cast()
//2.
auto p2_ = lexical_cast<int>(std::string("1"));
std::cout << "p2 = " << p2_ << std::endl; //displays 1, which is correct. calls overloaded lexical_cast()
//3.
std::locale locale_;
boost::date_time::format_date_parser<boost::gregorian::date, char> parser_("", locale_);
boost::date_time::special_values_parser<boost::gregorian::date, char> svp_;
boost::gregorian::date date_ = parser_.parse_date("2014-Dec-17", "%Y-%b-%d", svp_); //calls boost::lexical_cast(), but I want call to overloaded lexical_cast() instead.
}
catch(std::exception& e)
{
cout << e.what() << "n";
return 1;
}
return 0;
}
你的程序"工作",但与未定义的行为调情。
从技术上讲,重新定义不同翻译单元中完全相同符号的竞争定义违反了单一定义规则。你可以在这里侥幸逃脱,因为它只是关于函数实例,一次可以看到/选择一个。然而
- 这不会使"重载"库功能更有效。
- 这能够静默地更改包含在内部(不可见的?(依赖于
lexical_cast
的其他代码的行为。特别是对空字符串的默认构造值的静默"回退"是一种行为更改,库用户可能无法很好地应对。你基本上违反了其他客户与提升lexical_cast的合同
只有邀请用户在库命名空间内"重载"的结构模式,即在设计用于扩展点(TMP 中的自定义点(扩展库时。这通常需要
- 类的专业化(如
std::hash<>
、boost::hash<>
、boost::spirit::traits::is_container<>
、BOOST_FUSION_ADAPT_STRUCT()
等( - 添加一个函数的重载,该函数重载用户定义类型的参数(如
std::swap
,也许std::iter_swap
,但也boost::serialization::serialize
。重要的是,在这种情况下,通常命名空间入侵不是首选的,实际上也不是必需的,因为重载可以在与用户定义类型关联的命名空间内声明(例如std::swap(mypgrogram::typeA&, mypgrogram::typeA&)
甚至std::swap(boost::optional<mypgrogram::typeA>&, boost::optional<mypgrogram::typeA>&)
都可以在命名空间::mypgrogram
( 中完美定义,然后编译器可以使用参数相关查找 (ADL( 在两阶段查找中选择性地解析正确的重载
因此,除非 Boost Lexicalcast 记录了这样的自定义点供您使用,否则您无法可靠地将其用于其他模块(除非您可以以某种方式保证您的定义被所有调用看到(。在这种情况下,就地更改Boost Lexicalcast似乎更简单。毕竟,这正是您打算做的。
更新如果对 TU 中的包含项重新排序,则可以获得所需的效果。请注意,使用 SFINAE 来限制(在本例中(整型类型:
template<typename T>
typename std::enable_if<boost::is_integral<T>::value, T>::type
lexical_cast(const std::string &str)
住在科里鲁
#include <iostream>
#include <string>
#include <exception>
#include <boost/lexical_cast.hpp>
namespace boost
{
template<typename T>
typename std::enable_if<boost::is_integral<T>::value, T>::type
lexical_cast(const std::string &str)
{
std::cout << __PRETTY_FUNCTION__ << "n";
if(str.empty()) //handle preconditions here, some custom logic
return T();
T result;
if (!conversion::try_lexical_convert(str, result))
throw bad_lexical_cast();
return result;
}
}
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
using namespace std;
using namespace boost;
using namespace boost::posix_time;
using namespace boost::gregorian;
int main()
{
try
{
//1.
auto p1_ = lexical_cast<int>(std::string(""));
std::cout << "p1 = " << p1_ << std::endl; //displays 0, which is correct. calls overloaded lexical_cast()
//2.
auto p2_ = lexical_cast<int>(std::string("1"));
std::cout << "p2 = " << p2_ << std::endl; //displays 1, which is correct. calls overloaded lexical_cast()
//3.
std::locale locale_;
boost::date_time::format_date_parser<boost::gregorian::date, char> parser_("", locale_);
boost::date_time::special_values_parser<boost::gregorian::date, char> svp_;
boost::gregorian::date date_ = parser_.parse_date("2014-Dec-17", "%Y-%b-%d", svp_); //calls boost::lexical_cast(), but I want call to overloaded lexical_cast() instead.
std::cout << date_ << "n";
}
catch(std::exception& e)
{
cout << e.what() << "n";
return 1;
}
return 0;
}
指纹:
T boost::lexical_cast(const string&) [with T = int; std::string = std::basic_string<char>]
p1 = 0
T boost::lexical_cast(const string&) [with T = int; std::string = std::basic_string<char>]
p2 = 1
T boost::lexical_cast(const string&) [with T = short int; std::string = std::basic_string<char>]
T boost::lexical_cast(const string&) [with T = short int; std::string = std::basic_string<char>]
2014-Dec-17
- "error: no matching function for call to"构造函数错误
- 什么时候调用组成单元对象的析构函数
- 继承函数的重载解析
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- C++模板来检查友元函数的存在
- 递归函数计算序列中的平方和(并输出过程)
- 对RValue对象调用的LValue ref限定成员函数
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 为什么使用 "this" 指针调用派生成员函数?
- 将对象数组的引用传递给函数
- 函数调用中参数的顺序重要吗
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用不带参数的函数访问结构元素
- C++错误,隐 <function-style-cast> 式要求使用模板化类一次调用多个构造函数的多个转换
- C++ C++ 中的函数声明,键入 CAST
- 在[expr.static.cast]/4中,术语"一个可行函数"指的是什么
- 如何将双参数函数"cast"为单参数函数?
- 流输出和隐式void*cast运算符函数调用