没有前向声明,模板专业化无法解析 this-context 方法
Template specialisation unable to resolve this-context method without forward-declaration
我有一个模板 class,它大致采用下面给定代码的形式。
template <int index = 0>
struct Thing {
void Hello();
void Greet(const char *name);
};
这对于它的目的来说工作得很好,直到你决定尝试在它自己身上调用方法。假设您定义如下所示的方法。
template <>
void Thing<>::Greet(const char *name) {
Hello();
printf(", %s!\n", name);
}
template <>
void Thing<>::Hello() {
printf("Hello");
}
然后调用 Greet()
会产生一个明确的特化错误,我觉得这很奇怪。编译器应该通过其接口声明知道 this
的所有方法,但出于某种原因,它无法在这种情况下解析它。这可以通过以下两种方式之一解决;您必须转发声明对您自己调用的任何方法,或者确保这些方法的定义顺序确保您调用的方法已预先定义。
这个问题真的很烦人,因为我提供了接口声明,模板的任何特化都应该符合相同的接口,所以我真的不明白为什么编译器会抱怨这个——有没有解决问题的方法,而不用每个方法的前向声明污染代码,或者必须以特定方式对方法进行排序?
希望您有一些好的想法来更好地解决问题。提前致谢!
为了便于重现问题,这里有一个片段将调用有问题的方法。
int main(int argc, const char *argv[]) {
Thing<0> thing_with_zero;
thing_with_zero.Greet("World");
return 0;
}
您可以对整个 class 进行专业化以确保看到专业化:
// Primary template
// generic one
template <int index = 0>
struct Thing {
void Hello() {/*..*/}
void Greet(const char *name) {/*..*/}
};
// Specialization for index == 0
template <>
struct Thing<0> {
void Greet(const char *name) {
Hello();
printf(", %s!\n", name);
}
void Hello() {
printf("Hello");
}
};
或者,您可以在 if constexpr
(C++17) 的帮助下放弃专业化:
template <int index = 0>
struct Thing
{
void Greet(const char *name) {
if constexpr (index == 0) {
Hello();
printf(", %s!\n", name);
} else {
// ...
}
}
void Hello() {
if constexpr (index == 0) {
printf("Hello");
} else {
// ...
}
}
};
我有一个模板 class,它大致采用下面给定代码的形式。
template <int index = 0>
struct Thing {
void Hello();
void Greet(const char *name);
};
这对于它的目的来说工作得很好,直到你决定尝试在它自己身上调用方法。假设您定义如下所示的方法。
template <>
void Thing<>::Greet(const char *name) {
Hello();
printf(", %s!\n", name);
}
template <>
void Thing<>::Hello() {
printf("Hello");
}
然后调用 Greet()
会产生一个明确的特化错误,我觉得这很奇怪。编译器应该通过其接口声明知道 this
的所有方法,但出于某种原因,它无法在这种情况下解析它。这可以通过以下两种方式之一解决;您必须转发声明对您自己调用的任何方法,或者确保这些方法的定义顺序确保您调用的方法已预先定义。
这个问题真的很烦人,因为我提供了接口声明,模板的任何特化都应该符合相同的接口,所以我真的不明白为什么编译器会抱怨这个——有没有解决问题的方法,而不用每个方法的前向声明污染代码,或者必须以特定方式对方法进行排序?
希望您有一些好的想法来更好地解决问题。提前致谢!
为了便于重现问题,这里有一个片段将调用有问题的方法。
int main(int argc, const char *argv[]) {
Thing<0> thing_with_zero;
thing_with_zero.Greet("World");
return 0;
}
您可以对整个 class 进行专业化以确保看到专业化:
// Primary template
// generic one
template <int index = 0>
struct Thing {
void Hello() {/*..*/}
void Greet(const char *name) {/*..*/}
};
// Specialization for index == 0
template <>
struct Thing<0> {
void Greet(const char *name) {
Hello();
printf(", %s!\n", name);
}
void Hello() {
printf("Hello");
}
};
或者,您可以在 if constexpr
(C++17) 的帮助下放弃专业化:
template <int index = 0>
struct Thing
{
void Greet(const char *name) {
if constexpr (index == 0) {
Hello();
printf(", %s!\n", name);
} else {
// ...
}
}
void Hello() {
if constexpr (index == 0) {
printf("Hello");
} else {
// ...
}
}
};