【问题标题】:Why can I not pass this comparison function as a template argument?为什么我不能将此比较函数作为模板参数传递?
【发布时间】:2012-02-18 13:54:05
【问题描述】:

我正在尝试使用我为排序定义的函数创建一个 std::set, 但我收到错误:“错误:函数“GFX::MeshCompare”不是类型名称”

Mesh.h

namespace GFX
{
    struct Mesh
    {
        [...]
    };

    inline bool MeshCompare(const Mesh& a, const Mesh& b)
    {   
        return ( (a.pTech < b.pTech) ||
                 ( (b.pTech == a.pTech) && (a.pMaterial < b.pMaterial) ) ||
                 ( (b.pTech == a.pTech) && (a.pMaterial == b.pMaterial) && (a.topology < b.topology) ) 
               );
    }
};

渲染器.h

namespace GFX
{
    class Renderer
    {
    private:
        [...]
        std::set<Mesh, MeshCompare> m_Meshes;

    };
};

我做错了什么,我该如何解决?

【问题讨论】:

  • @Als 我尝试完全限定它,但没有成功。

标签: c++ stl std


【解决方案1】:

std::set 的第二个模板参数必须是 type,而不是 value

如果你想使用函数(它是value,而不是type),那么你必须将它作为参数传递给构造函数,这意味着你可以这样做这个:

class Renderer
{
    typedef bool (*ComparerType)(Mesh const&,Mesh const&);

    std::set<Mesh, ComparerType> m_Meshes;
public:
     Renderer() : m_Meshes(MeshCompare) 
     {        //^^^^^^^^^^^^^^^^^^^^^^^ note this
     }
};

或者,定义一个仿函数类,并将其作为第二个 type 参数传递给std::set

struct MeshComparer
{   
    bool operator()(const Mesh& a, const Mesh& b) const
    {
             return ( (a.pTech < b.pTech) ||
             ( (b.pTech == a.pTech) && (a.pMaterial < b.pMaterial) ) ||
             ( (b.pTech == a.pTech) && (a.pMaterial == b.pMaterial) && (a.topology < b.topology) ) );
   }
};

然后使用它:

std::set<Mesh, MeshComparer> m_Meshes;

【讨论】:

  • 参考告诉我我也可以传递一个函数?如果我去 std::set 的定义,我找不到明确的“类型名”,所以我不知道是什么导致了问题?
  • @xcrypt:模板参数函数/构造函数参数是有区别的。看我的回答。
  • 你知道std::foreach()吗?你可以在那里传递一个函数或一个仿函数,据我所知模板参数不能限制它,只有函数参数可以。你知道为什么这不起作用吗?编辑:我应该以不同的方式问我的问题:你知道为什么你不能传递一个值吗?
  • @xcrypt: std::for_each 是函数模板,它可以接受任何可调用实体作为第三个参数,这意味着你可以传递函数指针以及函子对象。请注意,它是您传递的对象,而不是类。
  • @xcrypt:是的。当模板定义使用关键字classtypename 时,它会要求您传递type,但当它使用已定义的类型时,例如intFun,则它要求您将一个值作为 模板参数 传递给模板。但是在 value 作为 template argument 的情况下,C++ 标准只允许您使用整数值:其中包括 int、long, char, enum , etc, including function addresses (which are always integral values); you cannot pass float, double`,以及其他类对象。
【解决方案2】:

如果你真的不想使用函子,你可以使用指向函数的指针:

std::set<Mesh, bool(*)(Mesh const&, Mesh const&)> set(MapCompare);

(在此示例代码中,我正在构建一个名为 set 的对象,这不是类数据成员。)

【讨论】:

    猜你喜欢
    • 2019-11-16
    • 1970-01-01
    • 1970-01-01
    • 2013-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-10
    • 1970-01-01
    相关资源
    最近更新 更多