我可以在 C++ 中即时创建匿名 class(接口的实现)吗
Can I create an anonymous on-the-fly class (implementation of an interface) in C++
在 C++ 中,我可以动态创建接口的实现吗(理想情况下绑定局部范围变量。)不确定如何更好地解释它,所以我将写下我希望代码看起来的内容喜欢(大致):
// Given the following:
class Visitor
{
virtual void visit(const Data& data) = 0;
}
class DataStore
{
void visitData(Visitor& visitor) { /** Invokes visitor with each item of data. */ }
}
// Imagine one would write something like:
void inSomeFunction(DataStore& store)
{
std::string myName = "bob";
class MyVisitor: public Visitor
{
public:
MyVisitor(const std::string& p): person(p);
virtual void visit(const Data& data) override
{
std::cout << person << " is visiting " << data << std::endl;
}
private:
std::string person;
}
MyVisitor myVisitor(myName);
store.visitData(myVisitor);
}
// Instead of the above, I want to write instead something like:
void inSomeFunction(DataStore& store)
{
std::string myName = "bob";
store.visitData(
class: public MyVisitor
{
virtual void visit(const Data& data) override
{
std::cout << myName << " is visiting " << data << std::endl;
}
}
);
}
我知道我在这里问了 2 个问题 - 你能不能像这样创建一个匿名 class,你能从本地范围绑定变量吗(就像我提到的 myName)。但我需要两者才能发挥作用。
如果无法完成上述操作,就简洁性/缺乏样板而言,最接近使用 C++11 lambda 或类似函数的方法是什么。
你可以通过多一层间接来实现:
#include <functional>
#include <utility>
class AdHocVisitor : public Visitor
{
public:
explicit AdHocVisitor(std::function<void(const Data&)> f) : f_(std::move(f)) {}
void visit(const Data& data) override { f_(data); }
private:
std::function<void(const Data&)> f_;
};
用法:
AdHocVisitor v([a, &b, this](const Data&) {});
store.visitData(v);
如果您有接口,那么您应该按照的建议进行操作。
但更好的方法是更改您的界面:
class DataStore
{
void visitData(Visitor& visitor) {
// bunch of calls to visitor.visit(...) ...
}
}
至:
template <class Visitor>
void visitData(Visitor visitor) {
// bunch of calls to visitor(...) ...
}
这样你就可以简单地写:
std::string myName = "bob";
store.visit([myName](const Data& data) {
std::cout << myName << " is visiting " << data << std::endl;
});
我认为这要自然得多。如果 DataStore
的界面不在你的控制范围内,那么这个答案就完全没有意义了。
在 C++ 中,我可以动态创建接口的实现吗(理想情况下绑定局部范围变量。)不确定如何更好地解释它,所以我将写下我希望代码看起来的内容喜欢(大致):
// Given the following:
class Visitor
{
virtual void visit(const Data& data) = 0;
}
class DataStore
{
void visitData(Visitor& visitor) { /** Invokes visitor with each item of data. */ }
}
// Imagine one would write something like:
void inSomeFunction(DataStore& store)
{
std::string myName = "bob";
class MyVisitor: public Visitor
{
public:
MyVisitor(const std::string& p): person(p);
virtual void visit(const Data& data) override
{
std::cout << person << " is visiting " << data << std::endl;
}
private:
std::string person;
}
MyVisitor myVisitor(myName);
store.visitData(myVisitor);
}
// Instead of the above, I want to write instead something like:
void inSomeFunction(DataStore& store)
{
std::string myName = "bob";
store.visitData(
class: public MyVisitor
{
virtual void visit(const Data& data) override
{
std::cout << myName << " is visiting " << data << std::endl;
}
}
);
}
我知道我在这里问了 2 个问题 - 你能不能像这样创建一个匿名 class,你能从本地范围绑定变量吗(就像我提到的 myName)。但我需要两者才能发挥作用。
如果无法完成上述操作,就简洁性/缺乏样板而言,最接近使用 C++11 lambda 或类似函数的方法是什么。
你可以通过多一层间接来实现:
#include <functional>
#include <utility>
class AdHocVisitor : public Visitor
{
public:
explicit AdHocVisitor(std::function<void(const Data&)> f) : f_(std::move(f)) {}
void visit(const Data& data) override { f_(data); }
private:
std::function<void(const Data&)> f_;
};
用法:
AdHocVisitor v([a, &b, this](const Data&) {});
store.visitData(v);
如果您有接口,那么您应该按照
但更好的方法是更改您的界面:
class DataStore
{
void visitData(Visitor& visitor) {
// bunch of calls to visitor.visit(...) ...
}
}
至:
template <class Visitor>
void visitData(Visitor visitor) {
// bunch of calls to visitor(...) ...
}
这样你就可以简单地写:
std::string myName = "bob";
store.visit([myName](const Data& data) {
std::cout << myName << " is visiting " << data << std::endl;
});
我认为这要自然得多。如果 DataStore
的界面不在你的控制范围内,那么这个答案就完全没有意义了。