C++ 操作员<&书信电报;智能指针的重载
我想重载操作符如果(我使用的是C++03名称空间),您可以使用第一个解决方案C++ 操作员<&书信电报;智能指针的重载,c++,visual-studio-2010,c++11,template-meta-programming,typetraits,C++,Visual Studio 2010,C++11,Template Meta Programming,Typetraits,我想重载操作符如果(我使用的是C++03名称空间),您可以使用第一个解决方案enable\u): 模板 类是\u funky:public boost::false\u type{}; 模板 类是\u funky:public boost::true\u type{}; 模板 typename boost::enable_if:type 操作员一些选项,请参见第二个live at 给定 #包括 #包括 使用名称空间std; 模板结构foo{ 虚拟FoO和操作符可能是你把自己置身于一个糟糕的竞技场
enable\u):
模板
类是\u funky:public boost::false\u type{};
模板
类是\u funky:public boost::true\u type{};
模板
typename boost::enable_if:type
操作员一些选项,请参见第二个live at
给定
#包括
#包括
使用名称空间std;
模板结构foo{
虚拟FoO和操作符可能是你把自己置身于一个糟糕的竞技场,使C++看起来像java。
C++指针、值和引用是不同的类型,具有不同的语义和操作。一般来说,将它们混合到同一语法中不是一个好主意。指针不是它们的值:它们可以指向它们引用的类型以外的类型(典型的,在继承的情况下)。因此,通常最好让指针取消引用保持显式
无论如何,保存到流中的“指针值”(不是“pointe*d*value”)没有任何意义,因为该值(内存地址)在流读取时将毫无意义
如果您正确地想要“保存所指向的对象”,那么在保存指针时,您应该保存一些告诉“您正在保存的对象类型”的内容,然后以多态方式保存对象(通过调用虚拟函数)o同时,您还必须跟踪循环引用,以避免多次保存同一对象(并将其作为不同对象加载回),因此还需要“标识”
要重新加载对象,应首先读取为描述类型而保存的元数据,并在此基础上创建相应的对象,然后将其成员重新分配给提取时加载的数据。(或者,如果仅保存了标识,则将指针指向已重新创建的相应对象)
所有这些东西都被冠以序列化的名称。有很多解决方案,你可能应该用谷歌搜索该密钥。你想让这个重载做什么?我不确定这是个好主意…与其写*f这听起来不是个好主意…@OliCharlesworth:想解释一下为什么吗?@ronag:它掩盖了什么发生。你抹去了指针和它的指针对象之间的区别。这是两个不同的对象,*
是保持区别的一个小代价。我不想保存“指向”的内容,我想“发送”到“指向”的内容。这个问题与序列化无关。@ronag它有:如果你想“发送”,必须有人“接收”。要“接收”,必须能够重建。如果某些信息丢失,则无法重建。保存只是“发送”和“接收”的一种特殊情况“发生在不同的时间。这里没有序列化,只是简单的方法调用。@ronad:我不坚持。但你几周后会回来!同样地。同时我建议你看看sehe的答案。它之所以有效,是因为(1)模板参数,(2)对于更复杂的CasyEa,模板模板参数位有点棘手。需要再次找到我的MMODEC++设计书籍。不知怎么没人注意到我之前的Sfink版本被破坏了(接受任何<代码> SyddypTr>代码>,因为指向不完整类型的指针不是问题)。我已经发布了一个更好的方法…
template<typename T>
struct foo
{
virtual foo& operator<<(const T& e) = 0;
};
foo<int> f1;
f1 << 1;
std::shared_ptr<foo<int>> f2(new foo<int>());
f2 << 1;
template<typename T, typename U>
const std::shared_ptr<T>& operator<<(const std::shared_ptr<T>& o, const U& e)
{
*o << e;
return o;
}
template<typename T, typename U>
const std::shared_ptr<foo<T>>& operator<<(const std::shared_ptr<foo<T>>& o, const U& e)
{
*o << e;
return o;
}
template<typename T, typename U>
const std::shared_ptr<foo<T>>& operator<<(const std::shared_ptr<foo<T>>& o, const T& e)
{
*o << e;
return o;
}
struct c
{
};
struct a
{
a();
a(c); // implicit conversion
};
struct b
{
operator a(); // implicit conversion
};
auto f = std::make_shared<foo<a>>();
f << c; // doesn't work.
f << b; // doesn't work.
template <typename T>
class is_funky : public boost::false_type {};
template <typename S>
class is_funky< Foo<S> > : public boost::true_type {};
template<typename T, typename U>
typename boost::enable_if< is_funky<T>, const boost::shared_ptr<T>& >::type
operator<<(const boost::shared_ptr<T>& o, const U& e)
{
*o << e;
return o;
}
#include <iostream>
#include <memory>
using namespace std;
template<typename T> struct foo {
virtual foo& operator<<(const T& e) const { std::cout << "check foo\n"; }
};
//////
// derived instances
struct derived : foo<int> {
virtual derived& operator<<(const int& e) const { std::cout << "check derived\n"; }
};
template<typename T> struct genericDerived : foo<T> {
virtual derived& operator<<(const T& e) const { std::cout << "check genericDerived\n"; }
};
template<typename T, typename U, template <typename> class X>
const std::shared_ptr<X<T>>& operator<<(const std::shared_ptr<X<T>>& o, const U& e)
{
*o << e;
return o;
}
int main()
{
auto f = make_shared<foo<int>>();
f << 1;
auto d = make_shared<derived>();
d << 2; // compile error
auto g = make_shared<genericDerived<int>>();
g << 3; // SUCCESS!
}
#include <type_traits>
namespace detail
{
template<typename Foo, typename T>
const std::shared_ptr<Foo>& dispatch_lshift(
const std::shared_ptr<Foo>& o, const T& e,
const std::true_type& enabler)
{
*o << e;
return o;
}
}
template<typename Foo, typename T>
const std::shared_ptr<Foo>& operator<<(const std::shared_ptr<Foo>& o, const T& e)
{
return detail::dispatch_lshift(o, e, std::is_convertible<Foo*, foo<T>* >());
}
int main()
{
auto f = make_shared<foo<int>>();
f << 1;
auto d = make_shared<derived>();
d << 2;
auto g = make_shared<genericDerived<int>>();
g << 3;
auto x = make_shared<int>();
// x << 4; // correctly FAILS to compile
}