简体   繁体   English

无法正确理解这种讨厌的 CRTPish 语法

[英]Can't get this pesky CRTPish syntax right

Consider the following code:考虑以下代码:

class A {
    virtual void foo() = 0;
};

template <template <typename... Ts> class SubA, typename... Ts>
class Helper : public A {
    static void bar();
    virtual void foo() override final {
        return bar();
    }
};

template <typename T>
class NiceA : Helper<NiceA, T> {    };

This compiles.这编译。 Edit: If I now add:编辑:如果我现在添加:

template <>
void Helper<NiceA, int>::bar()
{
    std::cout << "Hi." << std:: endl;
}

this explicit instantiation compiles.这个显式实例编译。 But if I add instead:但如果我添加:

template <typename T>
void Helper<NiceA, T>::bar()
{
    std::cout << "Hi." << std:: endl;
}

this fails with the error:这失败并出现错误:

a.cpp:22:28: error: invalid use of incomplete type ‘class Helper<NiceA, T>’
 void Helper<NiceA, T>::bar()
                            ^
a.cpp:10:7: error: declaration of ‘class Helper<NiceA, T>’
 class Helper : public A {
       ^

Why?为什么?

Note: Compiling with gcc 4.9.3.注意:使用 gcc 4.9.3 编译。

First of all, note that this has nothing to do with CRTP, ie it has nothing to do with NiceA inheriting from Helper .首先,请注意,这与 CRTP 无关,即与从Helper继承的NiceA无关。 Also, it has nothing to do with Helper inheriting from A or that virtual function.此外,它与从A或那个虚函数继承的Helper无关。

Thus, here is the actual code for the question:因此,这是问题的实际代码:

template <template <typename... Ts> class SubA, typename... Ts>
class Helper
{
  static void bar();
};

template <typename T>
class NiceA
{
};

template <>  // This compiles fine
void Helper<NiceA, int>::bar()
{
}

template <typename T>  // This does not
void Helper<NiceA, T>::bar()
{
}

int main()
{
}

Just saying, because by giving an MCVE you make the job easier for those who would like to give an answer.只是说,因为通过提供MCVE,您可以让那些想要给出答案的人更轻松地完成工作。

Now, why does it not compile?现在,为什么它不编译? You cannot partially specialize a single member function.您不能部分特化单个成员函数。 Period.时期。

You need to partially specialize the whole class.您需要部分专业化整个班级。

// Partially specialize Helper
template <typename T>
class Helper<NiceA, T>
{
  static void bar();
};

// Now implement the member function
template <typename T>
void Helper<NiceA, T>::bar()
{
}

You're simply mis-defining your member function:你只是错误地定义了你的成员函数:

template <typename T>
void Helper<NiceA, int>::bar()
{
    std::cout << "Hi." << std:: endl;
}

That would be the definition for a function template bar<T>() in Helper<NiceA, int> .这将是Helper<NiceA, int>函数模板bar<T>()的定义。 But bar() is just a normal function, so you don't need to specify any template parameters:但是bar()只是一个普通的函数,所以你不需要指定任何模板参数:

template <> // <== nothing
void Helper<NiceA, int>::bar()
{
    std::cout << "Hi." << std:: endl;
}

Clang's error is much more helpful in this particular instance:在这种特殊情况下,Clang 的错误更有帮助:

main.cpp:19:1: error: template parameter list matching the non-templated nested type 'Helper<NiceA, int>' should be empty ('template<>')
template <typename T>
^        ~~~~~~~~~~~~

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM