c++ - 隐藏重载虚函数的模板化访问者:使用 SFINAE?
问题描述
我正在编写一个模板化的访问者(取决于我们要访问的类型):
#include <iostream>
#include <memory>
#include <vector>
#include <string>
class INode;
class INodeVisitor {
public:
virtual void visit(INode&) = 0;
virtual ~INodeVisitor() = default;
};
template<typename ...Ts>
class TypedNodeVisitor;
template<typename T1, typename ...Ts>
class TypedNodeVisitor<T1, Ts...> : public TypedNodeVisitor<Ts...> {
public:
virtual void visit(INode &v) override {
if(auto p = dynamic_cast<T1*>(std::addressof(v))) {
apply(*p);
}
if constexpr(sizeof...(Ts) != 0) {
TypedNodeVisitor<Ts...>::visit(v);
}
}
//using TypedNodeVisitor<Ts...>::apply;
virtual void apply(T1 &) = 0;
};
template<>
class TypedNodeVisitor<> : public INodeVisitor {};
class INode {
public:
void accept(INodeVisitor &nv) {
nv.visit(*this);
}
virtual ~INode() = default;
};
class NodeB : public INode {};
class NodeA : public INode {};
class DrawerVisitor : public TypedNodeVisitor<NodeA, NodeB> {
public:
void apply(NodeA &) override {
std::cout << "A" << std::endl;
}
void apply(NodeB &) override {
std::cout << "B" << std::endl;
}
};
int main()
{
auto nodeA = std::make_shared<NodeA>();
auto nodeB = std::make_shared<NodeB>();
DrawerVisitor visitor;
nodeA->accept(visitor);
nodeB->accept(visitor);
return 0;
}
随着铿锵声,我得到这些警告:
prog.cc:49:30: note: in instantiation of template class 'TypedNodeVisitor<NodeA, NodeB>' requested here
class DrawerVisitor : public TypedNodeVisitor<NodeA, NodeB> {
^
prog.cc:31:18: note: hidden overloaded virtual function 'TypedNodeVisitor<NodeB>::apply' declared here: type mismatch at 1st parameter ('NodeB &' vs 'NodeA &')
virtual void apply(T1 &) = 0;
我确实理解问题可能是什么,但如果apply()
不在TypedNodeVisitor<>
.
有没有办法在std::enable_if
上使用using TypedNodeVisitor<Ts...>::apply
?
解决方案
有没有办法在 using 上使用 enable_if
TypedNodeVisitor<Ts...>::apply
?
据我所知,你不能:你不能模板化那种类型,using
所以你可以使用 SFINAE 来启用/禁用它。
我认为在“的空专业化中定义“应用的虚假定义”并没有错TypedNodeVisitor<>
(恕我直言,这是一个简单而优雅的解决方案)但是......如果你真的想避免它,你可以定义一个TypedNodeVisitor<T0>
专业化,而不是TypedNodeVisitor<>
, 为跟随
template <typename T0>
class TypedNodeVisitor<T0> : public INodeVisitor
{
public:
virtual void visit(INode &v) override {
if(auto p = dynamic_cast<T0*>(std::addressof(v))) {
apply(*p);
}
}
virtual void apply(T0 &) = 0;
};
这样你也可以避免if constexpr
在成员中进行测试visit()
(但你也可以避免它也添加一个假visit()
的 in TypedNodeVisitor<>
)
推荐阅读
- r - 如何从另一个栅格计算土地覆盖值?
- css - 为 SASS 中的每个规则添加前缀
- flutter - 导航器将所选收音机或文本的值传递到颤动的下一页
- java - 更改权限后“选择文件”按钮不起作用
- c++ - 我可以使用 decltype() 或其他方法通过指针获取真实类型吗?
- javascript - 在已经拆分的字符串上使用 Javascript 中的拆分函数
- ios - 在 Swift 中对二维数组进行排序
- python - Django:在 REST API ENDPOINT 中使用动态 API URL
- c# - HttpContextBase.User.Identity.Name 为空,带有 WindowsAuthentification true、anonymous false 和 Authorize 标签
- python - 创建神经网络以确定 XOR 门