打印对象的文本表示
Printing textual representation of objects
我对C++还比较陌生。如果我的术语不正确,请原谅。我试着四处寻找我的问题的答案,但我找不到(可能是因为我不能正确地表达我的问题)。如果有人能帮我,我将不胜感激。
我正在尝试编写一个类,用于创建可能包含对象或本机类型的文本表示的字符串。本质上,我有
private:
stringstream ss;
public:
template< typename T >
Message& operator<<( const T& value ) {
ss << value;
return *this;
}
过载<lt;运算符获取一些值,并尝试将其流式传输到字符串流中。如果T
类似于int
,或者如果类T
定义了方法operator std::string()
,我认为我的编译器对此很满意。然而,如果T
是类似于vector<int>
的某种类型,那么它将不再工作,因为vector<int>
没有定义operator std::string()
。
我是否可以重载这个运算符,以便如果T
定义了operator std::string()
,那么我打印文本表示,如果没有,我只打印它的地址?
谢谢。
这可以通过构建此处描述的has_insertion_operator
类型特性来实现:https://stackoverflow.com/a/5771273/4323
namespace has_insertion_operator_impl {
typedef char no;
typedef char yes[2];
struct any_t {
template<typename T> any_t( T const& );
};
no operator<<( std::ostream const&, any_t const& );
yes& test( std::ostream& );
no test( no );
template<typename T>
struct has_insertion_operator {
static std::ostream &s;
static T const &t;
static bool const value = sizeof( test(s << t) ) == sizeof( yes );
};
}
template<typename T>
struct has_insertion_operator :
has_insertion_operator_impl::has_insertion_operator<T> {
};
一旦我们有了这些,剩下的就相对简单了:
class Message
{
std::ostringstream ss;
public:
template< typename T >
typename std::enable_if<has_insertion_operator<T>::value, Message&>::type
operator<<( const T& value ) {
ss << value;
return *this;
}
template< typename T >
typename std::enable_if<!has_insertion_operator<T>::value, Message&>::type
operator<<( const T& value ) {
ss << &value;
return *this;
}
};
也就是说,如果定义了插入运算符,则打印值,否则打印其地址。
这并不依赖于定义到-std::string
运算符的转换——您只需要确保您的T
实例使用operator <<
"可打印"(通常在定义每个T
的同一范围中实现,例如命名空间或全局范围)。
这里有一个例子-为转换运算符到std::string
和流式运算符使用一些自定义特性:
#include <iostream>
#include <string>
template <class T>
struct traits
{
template <typename Q>
static auto hos(Q*) -> decltype(std::declval<const Q>().operator std::string());
static char hos(...);
constexpr static bool has_operator_string =
sizeof hos((T*){0}) != 1;
// ----
template <typename Q>
static auto isab(Q*) -> decltype(std::cout << std::declval<const Q>());
static char isab(...);
constexpr static bool is_streamable =
sizeof isab((T*){0}) != 1;
};
struct S
{
template <typename T>
typename std::enable_if<
traits<T>::has_operator_string,
S&>::type
operator<<(const T& value)
{
std::cout << "string() " << value.operator std::string() << 'n';
return *this;
}
template <typename T>
typename std::enable_if<!traits<T>::has_operator_string && traits<T>::is_streamable, S&>::type
operator<<(const T& value)
{
std::cout << "<< " << value << std::endl;
return *this;
}
template <typename T>
typename std::enable_if<
!traits<T>::has_operator_string &&
!traits<T>::is_streamable,
S&>::type
operator<<(const T& value)
{
std::cout << "T& @" << &value << std::endl;
return *this;
}
};
struct X
{
operator std::string() const { return "hi"; }
};
struct Y
{
};
int main()
{
std::cout << "> main()" << std::endl;
std::cout << "X() ";
S() << X();
Y y;
std::cout << "Y y; ";
S() << y;
std::cout << "Y() ";
S() << Y();
std::cout << ""text" ";
S() << "text";
std::cout << "< main()" << std::endl;
}
相关文章:
- 表示"accepting anything for this template argument" C++概念的通配符
- 文本文件中的单词链表
- 从命令行c++发送文本文件名
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 2D数组来自文本输入,中间有空格
- 如何将内容数组写入文本文件?
- 如何将ampl中的集合表示为c++中的向量
- 无法通过空白将文本文件行分隔为矢量
- 我正在使用嵌套的while循环来解析具有多行的文本文件,但由于某种原因,它只通过第一行,我不知道为什么
- 整数文本太大,无法用任何整数类型表示--C++
- 从文本文件读取到表示一个月的二维数组中
- Qt类型的标准文本表示是什么?
- 在写入文本文件时,如何表示替身
- 分配字符缓冲区以保存浮点的文本表示形式
- 以十进制、八进制和十六进制表示法标识整数文本是否与转义字符中的整数文本相同
- 为什么在文本冒险游戏中使用树数据结构来表示数据
- 打印对象的文本表示
- 将文本十六进制转换为实十六进制表示C++
- 如何在模板中表达字符串文本,该模板由用于表示文本的字符类型参数化
- 64位整数文本应该如何在C++中表示