1

给定以下课程

template <typename T>
class Plane
{
public:
    Plane<T>(T A, T B, T C, const Vector3<T>& vec):
        A(A),
        B(B),
        C(C),
        D(-1*A*vec.x-B*vec.y-C*vec.z)
    {

    }

    Plane<T>():
        A(0),
        B(0),
        C(0),
        D(0)
    {

    }


    bool CalculateTime(const Vector3<T>& r0,  const Vector3<T>& rd, T& result )
    {
        Vector3<T> vec(A,B,C);

        if ( vec.dot(rd))
        {
            result = -1;
            return false;
        }
        else
        {
            result = (vec.dot(r0) + D)/vec.dot(rd);
            return true;
        }
    }

    T A;
    T B;
    T C;
    T D;
};

出于某种奇怪的原因,当我执行以下操作时

    std::set<Plane<float> > s;
    s.insert(Plane<float>(10,20,30,Vector3f(10,30,40)));

这产生了一个巨大的错误

1>          with
1>          [
1>              T=float
1>          ]
1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\xtree(2245) : see declaration of 'std::operator <'
1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\xstddef(179) : while compiling class template member function 'bool std::less<_Ty>::operator ()(const _Ty &,const _Ty &) const'
1>          with
1>          [
1>              _Ty=Plane<float>
1>          ]
1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\xutility(559) : see reference to function template instantiation 'bool std::less<_Ty>::operator ()(const _Ty &,const _Ty &) const' being compiled
1>          with
1>          [
1>              _Ty=Plane<float>
1>          ]
1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\type_traits(743) : see reference to class template instantiation 'std::less<_Ty>' being compiled
1>          with
1>          [
1>              _Ty=Plane<float>
1>          ]
1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\xtree(1028) : see reference to class template instantiation 'std::is_empty<_Ty>' being compiled
1>          with
1>          [
1>              _Ty=std::less<Plane<float>>
1>          ]
1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\set(44) : see reference to class template instantiation 'std::_Tree<_Traits>' being compiled
1>          with
1>          [
1>              _Traits=std::_Tset_traits<Plane<float>,std::less<Plane<float>>,std::allocator<Plane<float>>,false>
1>          ]
1>          c:\users\awesome2\google drive\university\eng 3gc3\assignment 3\voxelmodeler\voxelmodeler\voxelcube.h(44) : see reference to class template instantiation 'std::set<_Kty>' being compiled
1>          with
1>          [
1>              _Kty=Plane<float>
1>          ]
1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\xstddef(180): error C2784: 'bool std::operator <(const std::move_iterator<_RanIt> &,const std::move_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::move_iterator<_RanIt> &' from 'const Plane<T>'
1>          with
1>          [
1>              T=float
1>          ]
1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\xutility(1983) : see declaration of 'std::operator <'
1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\xstddef(180): error C2784: 'bool std::operator <(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'const Plane<T>'
1>          with
1>          [
1>              T=float
1>          ]
1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\xutility(1259) : see declaration of 'std::operator <'
1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\xstddef(180): error C2784: 'bool std::operator <(const std::_Revranit<_RanIt,_Base> &,const std::_Revranit<_RanIt2,_Base2> &)' : could not deduce template argument for 'const std::_Revranit<_RanIt,_Base> &' from 'const Plane<T>'
1>          with
1>          [
1>              T=float
1>          ]
1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\xutility(1075) : see declaration of 'std::operator <'
1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\xstddef(180): error C2784: 'bool std::operator <(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'const Plane<T>'
1>          with
1>          [
1>              T=float
1>          ]
1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\utility(232) : see declaration of 'std::operator <'
1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\xstddef(180): error C2676: binary '<' : 'const Plane<T>' does not define this operator or a conversion to a type acceptable to the predefined operator
1>          with
1>          [
1>              T=float
1>          ]
4

2 回答 2

4

重要的部分是在您的错误消息的末尾:

...
error C2676: binary '<' : 'const Plane<T>' does not define this operator
or a conversion to a type acceptable to the predefined operator

std::set需要可订购的元素,即。它需要能够说一个对象小于另一个对象。

最简单的方法是operator <为您的类实现一个方法。不幸的是,定义“小于”对于 3 维平面的含义并不简单!

使用 可能值得研究std::unordered_set,它只要求元素具有可比性。

于 2012-11-28T20:57:18.700 回答
2

( setas multiset, mapand multimap) 需要一个比较函数或运算符。如果未指定set, multiset,mapmultimap使用std::lessfunctior 对象对集合中的元素进行纵坐标。所以你必须写这样的东西

template <typename T>
class Plane {
public:
    friend bool operator < (const Plane<T>& p1, const Plane<T>& p2)
    {
         return ???
    }
};

正如你所看到的,在一个系列中不是一个像平面这样的好类,也许更好unordered_set或者只是一个std::vector

于 2012-11-28T20:56:41.913 回答