与操作员重载和模板的未解决的外部符号 [英] Unresolved external symbol with operator overloading and templates

查看:149
本文介绍了与操作员重载和模板的未解决的外部符号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

试图编译此程序:

 命名空间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 ++ 。如何解决这个问题?并且我没有选择包含为成员函数,因为我需要更改操作数所引用的对象,而不使用复制构造函数(因为没有复制构造函数)。





更新:



如果我添加 template< typename T> 上面朋友Inner& ... ,我得到错误

 不能推导出'T'1>的模板参数。 
main.cpp(21):see declaration of'operator
++'
error C2783:
'MyNamespace :: Test< T> :: Inner& MyNamespace ::运算符++(MyNamespace :: Test< T> :: Inner&)':无法用
推导出模板
'T'的参数[
T = int
]
main.cpp(13):参见
的声明MyNamespace :: operator ++'
main.cpp(30):error C2675:unary'++':'MyNamespace :: Test< T> :: Inner'不定义此运算符或
转换为预定义运算符可接受的类型

with
[
T = int
]


解决方案

为什么你认为成员函数?实例成员应该正常工作:

 命名空间MyNamespace 
{
template< typename T&
class Test
{
public:
class Inner
{
int x;
public:
内部& 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;返回操作数; }
};

Inner i;
};
}

friend函数将放在命名空间范围,根据 [class.friend]


In trying to compile this program:

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;
}

I get the error

unresolved external symbol "class MyNamespace::Test::Inner & __cdecl MyNamespace::operator++(class MyNamespace::Test::Inner &)" (??EMyNamespace@@YAAAVInner@?$Test@H@0@AAV120@@Z) referenced in function _main

Which is weird because that's the exact signature of the non-member friend function operator++ that I defined. How do I fix this? And I do not have the option of including in as a member function because I need to change the object that the operand is referring to without using a copy constructor (because there is no copy constructor).


Update:

If I add template<typename T> above the friend Inner&..., I get the errors

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
]

解决方案

Why do you think it can't be a member function? An instance member should work just fine:

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

        Inner i;
    };
}

This doesn't require a copy constructor.

Defining a friend should work too, as long as the definition is with the friend declaration:

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

        Inner i;
    };
}

The friend function will be placed at namespace scope, according to [class.friend]

这篇关于与操作员重载和模板的未解决的外部符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆