我正在尝试用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
以上只是伪代码......这是我到目前为止所做的。我从Sean Parents的谈话中大量借用,可以在这里找到消息来源。
Model :: print没有看到Object :: print函数,我不明白为什么。它似乎与链接的源代码类似,它可以在那里工作......
从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();
}
百万感谢!
答案 0 :(得分:2)
进行一些改动以使其编译。
#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类是实际的文档类,以及向量&lt;&gt;的位置。住了。根据我的理解,你的课堂应该是文件的载体,但它不能像写的那样做。
答案 1 :(得分:1)
所以,我抓住了你的整体问题。
以下代码编译。它复制了一些东西(我很懒),但它支持使用简单For
生成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))
交叉产品。
#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);
}