我必须张贴相当多的代码,以解释我的情况。然而,这个问题很简单(参见我文章的最底部和最后一个代码段):
在SubscriptProxy::is
中,为什么调用this->get_element<Something>(parentElement);
时编译,而调用XYZ::get_element<Something>(parentElement);
时不编译?
File Element.hpp
class Element{};
File HelperFunctions.hpp
:
#include "Element.hpp"
namespace XYZ {
class Something;
template<typename T>
T get_element(Element* e) {
}
template<>
Something get_element(Element* e);
}
File HelperFunctions.cpp
:
#include "HelperFunctions.hpp"
#include "Something.hpp"
namespace XYZ {
template<>
Something get_element(Element* e) {
// Convert Element to Something somehow
return Something{};
}
}
File SubscriptProxy.hpp
:
#include "HelperFunctions.hpp"
namespace XYZ {
class Something;
template<typename C, typename D, typename E>
class SubscriptProxy {
C m_parent;
E m_index;
template<typename T>
T get_element(Element* e) const {
return XYZ::get_element<T>(e); // call helper function
}
template<typename T>
bool is(int index, Element*& e) const noexcept {
Element* parentElement;
if (!m_parent.template is<Something>(m_index, parentElement)) {
return false;
}
auto d = this->get_element<Something>(parentElement);
return d.template is<T>(index, e);
}
};
}
然后是Something.hpp
和Something.cpp
。它包含一个返回SubscriptProxy
实例的操作符:
#include "SubscriptProxy.hpp"
#include "HelperFunctions.hpp"
namespace XYZ {
class Something {
SubscriptProxy<Something, Something, int> operator[] (int index) const noexcept;
};
}
File Something.cpp
:
#include "Something.hpp"
namespace XYZ {
SubscriptProxy<Something, Something, int> Something::operator[] (int index) const noexcept {
return SubscriptProxy<Something, Something, int>{};
}
编译和工作正常。
然而,如果我改变SubscriptProxy::is
方法的实现如下:
template<typename T>
bool is(int index, Element*& e) const noexcept {
Element* parentElement;
if (!m_parent.template is<Something>(m_index, parentElement)) {
return false;
}
auto d = XYZ::get_element<Something>(parentElement);
return d.template is<T>(index, e);
}
…调用'get_element'时返回不完整类型'Something'.
为什么?
有两阶段的名称查找来检查模板的错误:
- 一个用于任何模板参数,所以编译器只检查非依赖的代码。
- 一个实例化(所以所有参数都是固定的)。
auto d = XYZ::get_element<Something>(parentElement);
现在不再依赖于模板,因此编译器可能会为此提供错误。
与this->get_element
,它取决于this
是模板