简体   繁体   English

具有不完整返回类型和无法解释的模板的变通方法

[英]Calling method with incomplete return type and my unexplainable template-workaround

I have to post quite a bit of code in order to explain my situation. 为了解释我的情况,我必须发布很多代码。 The question, however, is simple (see also at the very bottom of my post, and the last code segment): 但是,这个问题很简单(另请参见我的文章的最底部以及最后一个代码段):

In SubscriptProxy::is , why does it compile when calling this->get_element<Something>(parentElement); SubscriptProxy::is ,为什么在调用this->get_element<Something>(parentElement);时进行编译this->get_element<Something>(parentElement); but does not compile when calling XYZ::get_element<Something>(parentElement); 但是在调用XYZ::get_element<Something>(parentElement);时不会编译XYZ::get_element<Something>(parentElement); ?


File Element.hpp 文件Element.hpp

class Element{};

File HelperFunctions.hpp : 文件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 : 文件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 : 文件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);
        }
    };
}

And then we have Something.hpp and Something.cpp , of course. 然后,我们当然有Something.hppSomething.cpp It contains an operator which returns an instance of SubscriptProxy : 它包含一个返回SubscriptProxy实例的运算符:

#include "SubscriptProxy.hpp"
#include "HelperFunctions.hpp"

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

File Something.cpp : 文件Something.cpp

#include "Something.hpp"

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

This compiles and works fine. 这样可以编译并正常工作。

However, if I change the implementation of the SubscriptProxy::is method to the following: 但是,如果我将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);
        }

...it fails to compile with the error message: Calling 'get_element' with incomplete return type 'Something'. ...它无法编译并显示错误消息: 调用'get_element'具有不完整的返回类型'Something'。

Why? 为什么?

There are two-phase name lookup to check errors with template: 两个阶段的名称查找以检查模板错误:

  • one for any template argument, so compiler only check non dependant code. 一个用于任何模板参数,因此编译器仅检查非相关代码。
  • one at the instantiation (so all parameters are fixed). 实例化一个(因此所有参数都是固定的)。

auto d = XYZ::get_element<Something>(parentElement); is now longer template dependent, so compiler may provide error for this. 现在取决于模板的时间更长,因此编译器可能为此提供错误。

with this->get_element , it depends of this which is template. this->get_element ,这取决于的this是模板。

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

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