我正在尝试实现一个可变访问者类。
template<typename T>
class VisitorBaseFor {
protected:
virtual ~VisitorBaseFor() = default;
public:
virtual void visit(T &t) = 0;
};
template<typename... Ts>
class VisitorBase : public VisitorBaseFor<Ts>... {
public:
using VisitorBaseFor<Ts>::visit...;
};
我知道从那个超载技巧 https://dev.to/tmr232/that-overloaded-trick-overloading-lambdas-in-c17可变参数 using 声明应该是可能的,但是 MSVC 不编译我的代码,说我需要扩展 Ts,而 GCC 和 Clang 编译我的代码没有错误,请参阅here https://godbolt.org/z/7P-voB.
我缺少什么?这是 MSVC 错误还是(尚未)受支持?如果是的话,有没有办法解决这个问题?
除此之外,我尝试删除 using 声明,但随后对访问的调用由于某种原因变得不明确,即使 T 中的所有类都不能相互转换。 MSVC 正确诊断了这一点,但为什么它们甚至用于重载解析呢?
更新:这是至少自 2018 年 9 月 3 日起的已知错误。请参阅here https://developercommunity.visualstudio.com/content/problem/338188/pack-expansion-in-using-declarations-fails-with-te.html and here https://developercommunity.visualstudio.com/content/problem/326608/variadic-using-declarations-for-inheriting-constru.html.
代码确实是正确的,所以 msvc 的错误。
解决方法是手动执行递归:
template<typename T>
class VisitorBaseImpl {
protected:
virtual ~VisitorBaseImpl() = default;
public:
virtual void visit(T &t) = 0;
};
template<typename... Ts> class VisitorBase;
template<typename T>
class VisitorBase<T> : public VisitorBaseImpl<T>
{
};
template<typename T, typename... Ts>
class VisitorBase<T, Ts...> : public VisitorBase<T>, public VisitorBase<Ts...>
{
public:
using VisitorBase<T>::visit;
using VisitorBase<Ts...>::visit;
};
Demo https://godbolt.org/z/KvoWl3
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)