C++ 在模板中强制转换字符到int引用
[更新:雅克基本上回答了我的问题,但为了清楚起见,我正在更新这个问题。我还有一个问题,我在最后提到。] 我正在尝试编写一个序列化函数,作为其中的一部分,我需要将char转换为int,并保持其他类型不变。我编写了以下代码:C++ 在模板中强制转换字符到int引用,c++,templates,c++11,C++,Templates,C++11,[更新:雅克基本上回答了我的问题,但为了清楚起见,我正在更新这个问题。我还有一个问题,我在最后提到。] 我正在尝试编写一个序列化函数,作为其中的一部分,我需要将char转换为int,并保持其他类型不变。我编写了以下代码: #include<string> #include<iostream> #include<vector> using namespace std; template<typename T1> struct return_type
#include<string>
#include<iostream>
#include<vector>
using namespace std;
template<typename T1>
struct return_type {typedef T1 type;};
template<>
struct return_type<char> {typedef int type;};
template<typename T1>
typename return_type<T1>::type &type_transform(T1 &&t)
{
//If writing/reading char, cast it to int
return static_cast<typename return_type<T1>::type &>(t);
}
template<typename T1>
typename return_type<T1>::type &type_transform(T1 &t)
{
//If writing/reading char, cast it to int
return static_cast<typename return_type<T1>::type &>(t);
}
char fn()
{
return '\n';
}
main()
{
ofstream ofs("serialized.txt");
// ofs<<type_transform(fn()); error, should write 10
ofs.close();
ifstream ifs("serialized.txt");
// ifs>>type_transform(b); error, should read newline back
}
#包括
#包括
#包括
使用名称空间std;
模板
结构返回_type{typedef T1 type;};
模板
结构返回_type{typedef int type;};
模板
类型名返回类型::类型和类型转换(T1和t)
{
//如果写入/读取字符,则将其强制转换为int
返回静态_-cast(t);
}
模板
类型名返回类型::类型和类型转换(T1&t)
{
//如果写入/读取字符,则将其强制转换为int
返回静态_-cast(t);
}
char fn()
{
返回“\n”;
}
main()
{
ofs流(“serialized.txt”);
//类型转换(b);错误,应读回换行符
}
我得到一个错误:
从类型“char”到类型“return\u type::type&{aka int&}”的静态强制转换无效。
问题:
你需要重新思考你的设计
static\u cast
将不允许将char
或char&
转换为int&
。这就是在下面的通话中要发生的事情:
f1>>type_transform(variable);
如果
变量
的类型为char
,则无法将对int
的引用绑定到char
如果您想将某些内容作为另一种类型阅读,请多做一些工作:
template<class T>
struct io_storage {
T& t;
io_storage(io_storage&&)=default;
io_storage(T& tin):t(tin) {}
};
template<class T, class=void, class storage=io_storage<T>>
struct io_read_helper_t:storage {
friend std::istream& operator>>( std::istream& i, io_read_helper_t x ) {
return i >> x.t;
}
using storage::storage;
};
template<class T, class=void, class storage=io_storage<T>>
struct io_write_helper_t:storage {
friend std::ostream& operator<<( std::ostream& o, io_write_helper_t x ) {
return o << x.t;
}
using storage::storage;
};
template<class T, class impl=io_write_helper_t<T, void, io_read_helper_t<T>>>
struct io_helper_t : impl {
using impl::impl;
};
template<class T>
io_helper_t<T> io_helper( T& t ) { return {t}; }
template<class T>
io_write_helper_t<const T> io_helper( T const& t ) { return {t}; }
template<class T>
io_write_helper_t<const T> io_helper( T&& t ) { return {t}; }
template<class...>struct voider{using type=void;};
template<class...Ts>using void_t=typename voider<Ts...>::type;
template<class T>
struct io_type_as {};
template<> struct io_type_as<char>{ using type=int; };
template<class T>
using io_type_as_t=typename io_type_as<typename std::remove_const<T>::type>::type;
template<class T, class storage>
struct io_read_helper_t<T, void_t<io_type_as_t<T>>, storage>:storage {
using X=io_type_as_t<T>;
friend std::istream& operator>>( std::istream& i, io_read_helper_t x ) {
X tmp;
auto& r = i >> io_helper(tmp);
x.t = std::move(tmp);
return r;
}
using storage::storage;
};
template<class T, class storage>
struct io_write_helper_t<T, void_t<io_type_as_t<T>>, storage>:storage {
using X=io_type_as_t<T>;
friend std::ostream& operator<<( std::ostream& o, io_write_helper_t x )
{
return o << io_helper(X(x.t));
}
using storage::storage;
};
模板
结构io_存储{
T&T;
io_存储(io_存储&&)=默认值;
io_存储(T&tin):T(tin){}
};
模板
结构io\u读取\u帮助程序\u t:存储{
friend std::istream&operator>>(std::istream&i,io\U read\U helper\U t x){
返回i>>x.t;
}
使用存储::存储;
};
模板
结构io\u写入\u帮助程序\u t:存储{
friend std::ostream&operator>io_助手(tmp);
x、 t=std::move(tmp);
返回r;
}
使用存储::存储;
};
模板
结构io\u写入\u帮助程序\u t:存储{
使用X=io\u类型作为t;
friend std::ostream&operator 1.请发布如何调用它的实际代码。变量是什么,函数是什么()
?2.发布完整的编译器错误。您是否正在尝试重新设计boost::lexical_cast
?谢谢!我更新了问题,并在最后添加了一个问题。您能解释一下我们如何避免为具有左值引用和右值引用的函数模板编写单独的专门化吗?@user2308211拆分读写io helpers.Madeio\u helper
函数根据参数的r/l/constanss确定要使用哪个。代码拒绝读入右值(这通常是错误的标志:我建议不要更改它。将读入右值显式化),但将从右值写入。@user2308211和拼写错误修复,添加了实时示例。