无法正确使用这种讨厌的 CRTPish 语法
Can't get this pesky CRTPish syntax right
考虑以下代码:
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> { };
编译通过。 编辑: 如果我现在添加:
template <>
void Helper<NiceA, int>::bar()
{
std::cout << "Hi." << std:: endl;
}
此显式实例化编译。但如果我改为添加:
template <typename T>
void Helper<NiceA, T>::bar()
{
std::cout << "Hi." << std:: endl;
}
失败并出现错误:
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 {
^
为什么?
注意:使用 gcc 4.9.3 编译。
你只是错误定义了你的成员函数:
template <typename T>
void Helper<NiceA, int>::bar()
{
std::cout << "Hi." << std:: endl;
}
这将是 Helper<NiceA, int>
中函数模板 bar<T>()
的定义。但是 bar()
只是一个普通的函数,所以你不需要指定任何模板参数:
template <> // <== nothing
void Helper<NiceA, int>::bar()
{
std::cout << "Hi." << std:: endl;
}
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>
^ ~~~~~~~~~~~~
首先请注意,这与CRTP无关,即与NiceA
继承自Helper
无关。此外,它与 Helper
继承自 A
或该虚函数无关。
因此,这里是问题的实际代码:
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()
{
}
只是说,因为给一个 MCVE 会让那些想给出答案的人的工作变得更容易。
现在,为什么它不编译?您不能部分特化单个成员函数。期间.
您需要对整体进行部分特化 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()
{
}
考虑以下代码:
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> { };
编译通过。 编辑: 如果我现在添加:
template <>
void Helper<NiceA, int>::bar()
{
std::cout << "Hi." << std:: endl;
}
此显式实例化编译。但如果我改为添加:
template <typename T>
void Helper<NiceA, T>::bar()
{
std::cout << "Hi." << std:: endl;
}
失败并出现错误:
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 {
^
为什么?
注意:使用 gcc 4.9.3 编译。
你只是错误定义了你的成员函数:
template <typename T>
void Helper<NiceA, int>::bar()
{
std::cout << "Hi." << std:: endl;
}
这将是 Helper<NiceA, int>
中函数模板 bar<T>()
的定义。但是 bar()
只是一个普通的函数,所以你不需要指定任何模板参数:
template <> // <== nothing
void Helper<NiceA, int>::bar()
{
std::cout << "Hi." << std:: endl;
}
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>
^ ~~~~~~~~~~~~
首先请注意,这与CRTP无关,即与NiceA
继承自Helper
无关。此外,它与 Helper
继承自 A
或该虚函数无关。
因此,这里是问题的实际代码:
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()
{
}
只是说,因为给一个 MCVE 会让那些想给出答案的人的工作变得更容易。
现在,为什么它不编译?您不能部分特化单个成员函数。期间.
您需要对整体进行部分特化 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()
{
}