gpt4 book ai didi

c++ - 隐藏重载虚函数的模板化访问者 : SFINAE on using?

转载 作者:行者123 更新时间:2023-11-30 01:36:26 25 4
gpt4 key购买 nike

我正在编写一个模板化的访问者(取决于我们要访问的类型):

#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;
}

用 clang 我得到这些警告:

    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_ifusing TypedNodeVisitor<Ts...>::apply 上?

最佳答案

Is there a way to use enable_if on the using TypedNodeVisitor<Ts...>::apply ?

据我所知,你不能:你不能模板化那种类型的 using因此您可以使用 SFINAE 来启用/禁用它。

我认为定义“在 TypedNodeVisitor<> 的空特化中伪造的 apply 定义”没有错(恕我直言,这是一个简单而优雅的解决方案)但是......如果你真的想避免它,你可以定义一个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 constexprvisit() 中测试成员(但你可以避免它也在 visit() 中添加假的 TypedNodeVisitor<> )

关于c++ - 隐藏重载虚函数的模板化访问者 : SFINAE on using?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52136843/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com