【问题标题】:operator= Overload from a templated classoperator= 从模板类重载
【发布时间】:2014-12-14 18:28:18
【问题描述】:

我有一个项目将我的所有类模板化为 int、double 和 float,getCoordinate 返回一个 CCoordinate 类型的对象。

            tempCoordinate = m_shapes.at(i)->getCoordinate(j);

在我应用模板之前,它工作正常。但随后出现了一些错误。

据我了解,我需要丢失和 operator= 重载来对值进行类型转换,以防例如我有一个浮点数并且我收到一个 int,例如:

        CCoordinate<float> coorFloat;
        CCoordinate<int> coorInt = coorFloat

我怎样才能在我的课堂上创建这个?它需要什么格式? .

我以为它应该是这样的,但显然我错了。

//CCoordinate.h
template<class T>
class CCoordinate {
 //Code
 public:
 template<class U> template <class U> CCoordinate<T>
            operator= (const CCoordinate<U>& c1);
}

//CCoordinate.cpp
template <class U >
CCoordinate<U> CCoordinate<T>::operator= (const CCoordinate<U>& c1)
{
    // some kind of casting ? 
}

我的错误:

19:06:43 **** Incremental Build of configuration Debug for project ShapesRefV2 ****
Info: Internal Builder is used for build
g++ -O0 -g3 -Wall -c -fmessage-length=0 -Werror=return-type -o "myCode\\CRectangle.o"      "..\\myCode\\CRectangle.cpp" 
g++ -O0 -g3 -Wall -c -fmessage-length=0 -Werror=return-type -o "myCode\\CPlane.o"    "..\\myCode\\CPlane.cpp" 
..\myCode\CPlane.cpp: In instantiation of 'GraSys::CRectangle<T>       GraSys::CPlane<T>::boundingBox(std::string, std::string) [with T = int; std::string =    std::basic_string<char>]':
..\myCode\CPlane.cpp:165:24:   required from here
..\myCode\CPlane.cpp:115:20: error: no match for 'operator=' (operand types are   'GraSys::CCoordinate<double>' and 'const GraSys::CCoordinate<int>')
  tempCoordinate = m_shapes.at(i)->getCoordinate(j);
                ^
..\myCode\CPlane.cpp:115:20: note: candidate is:
In file included from ..\myCode\CGraphicElement.h:14:0,
               from ..\myCode\CPlane.h:11,
               from ..\myCode\CPlane.cpp:9:
..\myCode\CCoordinate.h:17:7: note: GraSys::CCoordinate<double>&   GraSys::CCoordinate<double>::operator=(const GraSys::CCoordinate<double>&)
class CCoordinate
        ^
..\myCode\CCoordinate.h:17:7: note:   no known conversion for argument 1 from 'const    GraSys::CCoordinate<int>' to 'const GraSys::CCoordinate<double>&'
..\myCode\CPlane.cpp: In instantiation of 'GraSys::CRectangle<T> GraSys::CPlane<T>::boundingBox(std::string, std::string) [with T = float; std::string =   std::basic_string<char>]':
..\myCode\CPlane.cpp:166:24:   required from here
..\myCode\CPlane.cpp:115:20: error: no match for 'operator=' (operand types are 'GraSys::CCoordinate<double>' and 'const GraSys::CCoordinate<float>')
     tempCoordinate = m_shapes.at(i)->getCoordinate(j);
                    ^
..\myCode\CPlane.cpp:115:20: note: candidate is:
In file included from ..\myCode\CGraphicElement.h:14:0,
                 from ..\myCode\CPlane.h:11,
                 from ..\myCode\CPlane.cpp:9:
..\myCode\CCoordinate.h:17:7: note: GraSys::CCoordinate<double>&   GraSys::CCoordinate<double>::operator=(const GraSys::CCoordinate<double>&)
 class CCoordinate
       ^
..\myCode\CCoordinate.h:17:7: note:   no known conversion for argument 1 from 'const GraSys::CCoordinate<float>' to 'const GraSys::CCoordinate<double>&'

19:06:44 Build Finished (took 674ms)

【问题讨论】:

标签: c++ templates casting operator-overloading


【解决方案1】:

在成员声明中template &lt;class U&gt;的次数太多了,该成员应该返回一个对*this的引用,所以它需要返回CCordinate &amp;(如果你省略它,&lt;T&gt;是隐含的):

// Remove this       vvvvvvvvvvvvvvvvvv
template<class U> /* template <class U> */
CCoordinate & operator= (const CCoordinate<U>& c1);
//          ^- Return type changed to be a reference.

由于成员是模板而类是模板,因此您有两个级别的模板。实现成员时需要指定这两个级别。

它也返回了错误的类型(它返回CCoordinate&lt;U&gt;,但你已在类中声明它返回CCoordinate&lt;T&gt;)。

// You need the T template as well.
// vvvvvvvvvvvvvvv
template <class T>
template <class U>
CCoordinate<T> & CCoordinate<T>::operator= (const CCoordinate<U>& c1)
//          ^  ^- Added reference as per above.
//          \---- Changed to T; U makes no sense here and conflicts with your member
//                declaration in the class.
{
    // Your logic to make the conversion.

    return *this;
}

【讨论】:

  • 它可以编译,但缺少一些东西。未定义对 `GraSys::CCoordinate& GraSys::CCoordinate::operator=(GraSys::CCoordinate const&)' 的引用
  • @IzonFreak 模板实现需要在标头中,以便编译器可以在使用它们时实例化它们。您可能将其放在.cpp 文件中。 You can't do that(除非您明确实例化您需要的所有类型参数,但我怀疑您是否正在这样做,而且您也不想这样做)。
【解决方案2】:

您的尝试存在两个问题。更简单的问题是operator= 的声明语法有一个额外的template &lt;class U&gt;。它应该是这样的:

template<class U> CCoordinate<T>
            operator= (const CCoordinate<U>& c1);

然而,即使是正确定义的operator= 也不允许你写

CCoordinate<float> coorFloat;
CCoordinate<int> coorInt = coorFloat;

这是因为copy initializescoorInt上方的第二行。 operator= 不考虑用于复制初始化 - 它只查看 user-defined conversions 在这种情况下只包括非显式构造函数和非显式转换函数。

【讨论】:

    猜你喜欢
    • 2016-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-24
    相关资源
    最近更新 更多