尝试应用肖恩父母谈话"inheritance is the base class of evil"中的模式
Trying to apply the pattern from sean parent's talk "inheritance is the base class of evil"
https://ideone.com/1Pkxwe
我正在尝试在 c++ 中理解。我想从一些其他可迭代容器中构造一个For
实例。稍后我将传递一个函数,For
将对其内容调用该函数。
我还没有通过异构向量,但我正在想象
void f(int i, char c) {
cout << i << " " << c << endl;
}
For(1,2)('a','b').yield(f);
将打印
1 a
1 b
2 a
2 b
以上只是伪代码...这就是我目前所拥有的。我大量借鉴了肖恩父母的谈话,这个来源可以在这里找到。
https://raw.githubusercontent.com/boostcon/cppnow_presentations_2012/master/fri/value_semantics/value_semantics.cpp
模型::p rint 看不到 Object::p rint 函数,我不明白为什么。它似乎类似于链接的源代码,并且在那里工作......
来自 IDEONE 的错误输出
prog.cpp: In instantiation of ‘void Object::Model<T>::print() [with T = std::__cxx11::basic_string<char>]’:
prog.cpp:58:5: required from here
prog.cpp:26:22: error: no matching function for call to ‘Object::Model<std::__cxx11::basic_string<char> >::print(std::__cxx11::basic_string<char>&)’
print(data);
~~~~~^~~~~~
prog.cpp:25:18: note: candidate: void Object::Model<T>::print() [with T = std::__cxx11::basic_string<char>]
void print() {
^~~~~
prog.cpp:25:18: note: candidate expects 0 arguments, 1 provided
prog.cpp: In instantiation of ‘void Object::Model<T>::print() [with T = int]’:
prog.cpp:58:5: required from here
prog.cpp:26:22: error: no matching function for call to ‘Object::Model<int>::print(int&)’
print(data);
~~~~~^~~~~~
prog.cpp:25:18: note: candidate: void Object::Model<T>::print() [with T = int]
void print() {
^~~~~
prog.cpp:25:18: note: candidate expects 0 arguments, 1 provided
和代码
#include <vector>
#include <string>
#include <functional>
#include <iostream>
using namespace std;
struct Object {
template <typename T>
Object(T t) : model(new Model<T>(t)) {
cout << "construct object from T" << endl;
}
friend void print(string str) {
cout << str << endl;
}
friend void print(int i) {
cout << i << endl;
}
struct Concept {
virtual void print() =0;
};
template <typename T>
struct Model : Concept {
Model(T t) : data(t) {}
void print() {
print(data);
}
T data;
};
Concept *model;
};
struct For {
For() {
cout << "default construct For" << endl;
}
For(Object o) {
cout << "construct For from object and push back" << endl;
objects.push_back(o);
}
For operator()(Object o) {
cout << "push back object" << endl;
objects.push_back(o);
return *this;
}
void print() {
for(auto o : objects) {
o.model->print();
}
};
vector<Object> objects;
};
int main() {
auto heterogeneous = For(1)(string("hello"));
function<void(int)> f = [](int i)->void{ cout << i << endl; };
heterogeneous.print();
}
一百万感谢!
进行一些更改以使其编译。
#include <vector>
#include <string>
#include <functional>
#include <iostream>
using namespace std;
template <typename T>
void print(T&&); // <- so that Object::Model knows what you want.
struct Object {
template <typename T>
Object(T t) : model(new Model<T>(t)) {
cout << "construct object from T" << endl;
}
friend void print(string str) {
cout << str << endl;
}
friend void print(int i) {
cout << i << endl;
}
struct Concept {
virtual ~Concept() = default; // <- you MUST have a virtual dtor
virtual void print() =0;
};
template <typename T>
struct Model : Concept {
Model(T t) : data(t) {}
void print() {
::print(data); // <-- the :: because Model::print hid what you wanted to call
}
T data;
};
Concept *model;
};
struct For { // I don't recall this from Sean's talk. I don't think it
// works as intended.
For() {
cout << "default construct For" << endl;
}
For(Object o) {
cout << "construct For from object and push back" << endl;
objects.push_back(o);
}
For operator()(Object o) {
cout << "push back object" << endl;
objects.push_back(o);
return *this;
}
void print() {
for(auto o : objects) {
o.model->print();
}
};
vector<Object> objects;
};
// print functions for your types.
void print(const std::string& s)
{
std::cout << s << "n";
}
void print(const int& i)
{
std::cout << i << "n";
}
int main() {
auto heterogeneous = For(1)(string("hello")); // this adds [1,"hello"] to the model
// is this what you want?
//function<void(int)> f = [](int i)->void{ cout << i << endl; };
heterogeneous.print();
}
在 Sean 的演讲中,你的 Object 类是什么是实际的文档类,这就是向量<>存在的地方。据我了解,你的 for class 应该是文档的载体,但它不能按照书面形式做到这一点。
所以,我试了一下你的整体问题。
编译以下代码。 它复制的东西有点多(我很懒),但它支持使用一个简单的For(a,b,c)(1,2,3)
生成((a,1),(a,2),(a,3),(b,1),(b,2),(b,3),(c,1),(c,2),(c,3))
进行For
交叉产品。
#include <vector>
#include <string>
#include <functional>
#include <iostream>
// Default print; stream to cout:
template <typename T>
void print(T const& t){ std::cout << t <<"n"; }
// Functional-style loops:
struct Object;
// a loop-body is a "sink" of Objects. In C++, it is the part after the control flow, the code
// that gets run each iteration.
using Body=std::function<void(Object)>;
// a loop is a "sink" of loop-bodies. Read this as "loop over the contents of an Object, doing Body"
using Loop=std::function<void(Body)>;
// default foreach: return a loop that just visits yourself:
template <typename T>
Loop foreach(T const& t) {
return [t](Body body){ body(t); };
}
// custom printing:
inline void print(std::string const& str) {
std::cout << """ << str <<""" << std::endl;
}
inline void print(int i) {
std::cout << "Integer: "<< i << std::endl;
}
// such custom prints can go here, or in the namespace of the type.
// Objects are actually smart pointers to type-erased data:
struct Object {
template <typename T>
Object(T t) : model(std::make_shared<Model<T>>(std::forward<T>(t))) {
// std::cout << "construct object from T" << std::endl;
}
friend void print(Object o){
o.model->do_print();
}
friend Loop foreach(Object o){
return o.model->do_foreach();
}
struct Concept {
virtual void do_print() =0;
virtual Loop do_foreach() = 0;
// no dtor, as shared ptr handles that
};
template <typename T>
struct Model final : Concept {
Model(T t) : data(std::forward<T>(t)) {}
void do_print() override {
print(data);
}
Loop do_foreach( ) override {
return foreach(data);
}
T data;
};
std::shared_ptr<Concept> model;
};
struct For {
For() {}
template<class...Ts>
For(Ts const&...ts):
objects({ts...})
{}
// given an Object o, return that object's contents
// in a For.
static For box(Object o) {
For tmp;
foreach(o)([&tmp](Object o){ tmp+=o; });
return tmp;
}
For(For const&)=default;
For& operator+=(Object o){ objects.push_back(o); return *this; }
For operator+(Object o) const { For tmp=*this; tmp+= o; return tmp; }
For operator*(For rhs)const{
For tmp;
for( auto o1 : objects )
for( auto o2 : rhs.objects )
{
tmp += box(o1) + o2;
}
return tmp;
}
For& operator*=(For rhs){
*this = *this*rhs;
return *this;
}
template<class...Ts>
For operator()(Ts const&... ts) {
*this *= For(ts...);
return *this;
}
friend Loop foreach(For const& f){
return [f](Body body){
for(auto o : f.objects) {
body(o);
}
};
}
friend void print(For f) {
std::cout << "{";
for(auto o : f.objects) {
print(o);
}
std::cout << "}n";
};
std::vector<Object> objects;
};
测试代码:
int main() {
auto a = For(std::string("hello"),42)(1,-1);
auto b = a;
b('a','b','c');
std::cout <<"a:n";
print(a);
std::cout <<"b:n";
print(b);
}
相关文章:
- C++核心准则 C35 对于接口类"A base class destructor should be either public and virtual, or protected and nonv
- 当初始值设定项是基类名时'initializer does not name a non-static data member or base class'错误
- Visual Studio MFC C++ "CFormView" "base class"下拉列表中缺少
- 尝试应用肖恩父母谈话"inheritance is the base class of evil"中的模式
- 有没有办法在Python中做"template base class"?
- 通过"a pointer of the base class"访问未在基类中声明的子类的方法或属性(动态)
- 多态性>错误:'no known conversion from derived class to base class'
- Clang - 删除某些文件的"conversion function converting <A> to base class <B> will never be used"
- 禁止从模板类的库标头中"Base class ‘class X’ should be explicitly initialized in the copy constructor"
- "virtual base class in the case of multilevel inheritance"有意义吗
- 无法将"member pointer to derived class"转换为"member pointer to base class"
- 派生类'no type named my_data in <base class>'中的错误
- "polymorphic base class"是C++标准的一部分吗?
- 子构造函数无法识别基类的成员:平均值,西格玛"is not a nonstatic data member or base class"
- "Base class undefined."
- 如何在C++实现继承并解决错误"parent class is not accessible base of child class"?
- Qt 序列化。QDataStream & operator<< for base class QPolygonF
- 关于肖恩·帕伦特谈话的澄清 "Inheritance is the base class of evil"
- int 和 double 的均匀随机分布"base class"?
- 硬件:C++错误"trying to initialize Abstract base class"