Why am I getting "error: type name is not allowed" with these spaghetti templates?

Why am I getting "error: type name is not allowed" with these spaghetti templates?

我有以下代码和一些 "spaghetti" 模板:

template <typename A, typename B, typename... Args>
class C {
    /*... */
    Bar& getBar() { /* ... */ }
public:
    template <typename U>
    static void Foo() {
        A a = getA<U>();
        Baz& bar = getBar();
        bar.frob<U>(a); /* @@@ */
    }
    /*... */
}

/* no template */
class D : public C<SomeA, D, const SomeE&> { /* ... */ }

/* no template */
class F : public D { /* ... */}

当我尝试使用以下语句编译函数时:

D::Foo<F>();

我在标记为 @@@ 的行中收到错误 type name is not allowed。为什么我会得到那个?我知道当您尝试调用具有类型名称的函数时您会得到它,但它看起来不像我在这里做的那样。

这是典型的模板歧义,不幸的是,如果您不了解它,很难注意到它。答:需要写bar.template frob<U>(a); 原因:见this Q&A.