【问题标题】:Unresolved external symbol with operator overloading and templates带有运算符重载和模板的未解析外部符号
【发布时间】:2011-10-21 21:43:55
【问题描述】:

在尝试编译这个程序时:

namespace MyNamespace {
    template<typename T>
    class Test {
    public:
        class Inner {
            int x;
            public:
                    Inner() : x(0) { }
            friend Inner& operator++(Inner& rhs);
        };

        Inner i;
    };
}

template<typename T>
typename MyNamespace::Test<T>::Inner& operator++(typename MyNamespace::Test<T>::Inner& rhs) {
    rhs = MyNamespace::Test<T>::Inner(rhs.x + 1);

    return rhs;
}

int main() {
    MyNamespace::Test<int> t;
    MyNamespace::Test<int>::Inner i = t.i;
    ++i;
}

我得到了错误

未解析的外部符号“class MyNamespace::Test::Inner & __cdecl MyNamespace::operator++(class MyNamespace::Test::Inner &)”(??EMyNamespace@@YAAAVInner@?$Test@H@0@AAV120 @@Z) 在函数_main中引用

这很奇怪,因为这是我定义的非会员朋友函数operator++ 的确切签名。我该如何解决?而且我没有将 in 作为成员函数包含在内的选项,因为我需要在不使用复制构造函数的情况下更改操作数所引用的对象(因为没有复制构造函数)。


更新:

如果我在friend Inner&amp;... 上方添加template&lt;typename T&gt;,则会出现错误

could not deduce template argument for 'T' 1>         
main.cpp(21) : see declaration of 'operator
++' 
error C2783:
'MyNamespace::Test<T>::Inner &MyNamespace::operator++(MyNamespace::Test<T>::Inner &)' : could not deduce template
argument for 'T' with
[
              T=int
]          
main.cpp(13) : see declaration of
'MyNamespace::operator ++' 
main.cpp(30): error C2675: unary '++' : 'MyNamespace::Test<T>::Inner' does not define this operator or a
conversion to a type acceptable to the predefined operator

with
[
              T=int
]

【问题讨论】:

    标签: c++ templates operator-overloading linker-errors


    【解决方案1】:

    为什么你认为它不能是成员函数?实例成员应该可以正常工作:

    namespace MyNamespace
    {
        template<typename T>
        class Test
        {
        public:
            class Inner
            {
                int x;
            public:
                Inner& operator++( void ) { ++x; return *this; }
            };
    
            Inner i;
        };
    }
    

    这不需要复制构造函数。

    定义朋友也应该有效,只要定义与朋友声明一起:

    namespace MyNamespace
    {
        template<typename T>
        class Test
        {
        public:
            class Inner
            {
                int x;
            public:
                friend Inner& operator++( Inner& operand ) { ++operand.x; return operand; }
            };
    
            Inner i;
        };
    }
    

    友元函数将根据[class.friend]放置在命名空间范围内

    【讨论】:

    • 天哪,本曼,我从来不知道你可以把朋友函数的主体和朋友声明本身放在一起!太棒了,感谢您的宝贵时间。 +1 并回答。
    • 顺便问一下,如果你不介意我问,你是从哪里学来的?
    • @Seth:我不记得第一次看到它是在哪里了。但它在 C++ 标准中明确描述:“当且仅当类是非本地类 (9.8)、函数名称是非限定的并且函数具有命名空间范围时,才能在类的友元声明中定义函数。”还有一个过于简单的例子。
    猜你喜欢
    • 2016-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-18
    • 2011-08-12
    • 2018-12-04
    • 1970-01-01
    • 2014-06-13
    相关资源
    最近更新 更多