调用具有不完整返回类型的方法和我无法解释的模板 - 解决方法

时间:2015-08-05 12:22:30

标签: c++ templates compiler-errors forward-declaration

我必须发布相当多的代码才能解释我的情况。然而,问题很简单(另见我的帖子的最底部和最后一段代码段):

SubscriptProxy::is中,为什么在调用this->get_element<Something>(parentElement);时编译但在调用XYZ::get_element<Something>(parentElement);时不编译?

档案Element.hpp

class Element{};

档案HelperFunctions.hpp

#include "Element.hpp"

namespace XYZ {
    class Something;

    template<typename T>
    T get_element(Element* e) {
    }

    template<>
    Something get_element(Element* e);
}

档案HelperFunctions.cpp

#include "HelperFunctions.hpp"
#include "Something.hpp"

namespace XYZ {
    template<>
    Something get_element(Element* e) {
       // Convert Element to Something somehow
       return Something{};
    }
}

档案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.hppSomething.cpp。它包含一个返回SubscriptProxy

实例的运算符
#include "SubscriptProxy.hpp"
#include "HelperFunctions.hpp"

namespace XYZ {
    class Something {
        SubscriptProxy<Something, Something, int> operator[] (int index) const noexcept;
    };
}

档案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);
        }

...它无法使用错误消息进行编译:使用不完整的返回类型“Something”调用'get_element'。

为什么?

1 个答案:

答案 0 :(得分:1)

使用模板检查错误two-phase name lookup

  • 一个用于任何模板参数,因此编译器只检查非依赖代码。
  • 实例化中的一个(因此所有参数都是固定的)。

auto d = XYZ::get_element<Something>(parentElement);现在更长时间依赖于模板,因此编译器可能会为此提供错误。

this->get_element,取决于作为模板的this