使用声明的 Variadic base class 无法在 MSVC 中编译

Variadic base class using declaration fails to compile in MSVC

我正在尝试实现可变访问者 class。

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

我从that overload trick that variadic using declarations should be possible, but MSVC does not compile my code saying I need to expand Ts while both GCC and Clang compile my code without errors, see here.

知道

我错过了什么?这是一个 MSVC 错误还是只是(还)不受支持?如果是,是否有解决此问题的方法?

除此之外,我曾尝试删除 using 声明,但由于某种原因,对 visit 的调用变得模棱两可,即使 Ts 中的所有 classes 都不能相互转换。 MSVC 对此进行了正确诊断,但为什么它们甚至用于重载解析?

更新:这是一个已知错误,至少从 2018 年 9 月 3 日开始。请参阅 here and here

代码确实正确,所以是 msvc 的 bug。

解决方法是手动执行递归:

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