C++ 使用未绑定的函数对象实例化函数对象会导致l值错误

C++ 使用未绑定的函数对象实例化函数对象会导致l值错误,c++,lvalue,function-object,C++,Lvalue,Function Object,我有以下功能对象: /// function object wrapping node and label data into strings of DOT code /// requires as template parameters 2 function objects that define behaviour /// converting node and lable into strings. Requires as first template /// argument the g

我有以下功能对象:

/// function object wrapping node and label data into strings of DOT code
/// requires as template parameters 2 function objects that define behaviour
/// converting node and lable into strings. Requires as first template
/// argument the graph edge type
template<typename GRAPHEDGE, typename NodeToStringConverter,
         typename LabelToStringConverter>
struct DOTWrapper
{

    typedef NodeToStringConverter NodeConverter;
    typedef LabelToStringConverter LabelConverter;

    /// initialises to-string-converter objects
    DOTWrapper(NodeConverter& nc, LabelConverter& lc): nts(nc), lts(lc){}

    std::string start() const
    {
        return ("digraph  {\n");
    }

    // wrap an egde into dot code
    std::string wrap_edge(const GRAPHEDGE& e) const
    {
        // n needs to be to_string-able
        return ("\t\""+nts(e.source())+"\""+" -> "+"\""+nts(e.target())+"\""+
                " [ label = \""+lts(e.label())+"\" ];\n");
    }

    std::string finish() const { return "}\n"; }

    const NodeToStringConverter nts;
    const LabelToStringConverter lts;

};

template<typename Node>
struct NTSint
{

    std::string operator()(const Node& node) const { return node; }
};

template<typename Label>
struct LTSstr
{

    std::string operator()(const Label& label) const { return label; }
};
///函数对象将节点和标签数据包装为点代码字符串
///需要2个定义行为的函数对象作为模板参数
///将节点和标签转换为字符串。需要作为第一个模板
///参数指定图形的边类型
模板
结构点包装器
{
typedef NodeToStringConverter NodeConverter;
typedef LabelToStringConverter LabelConverter;
///初始化字符串转换器对象
点包装器(NodeConverter&nc、LabelConverter&lc):nts(nc)、lts(lc){}
std::string start()常量
{
返回(“有向图{\n”);
}
//将egde包装成点代码
标准::字符串包边(常量图形边缘和e)常量
{
//n需要是可字符串的
返回(“\t\”“+nts(e.source())+”\”“+”->“+”\”“+nts(e.target())+”\”+
“[label=\”“+lts(e.label())+”\“];\n”);
}
std::string finish()常量{return“}\n”;}
常数nodetostringts;
常数LABELTOSTRINGLTS;
};
模板
结构NTSint
{
std::string操作符()(const Node&Node)const{return Node;}
};
模板
结构LTSstr
{
std::string操作符()(const Label&Label)const{return Label;}
};
当我尝试像这样实例化包装器对象时:

typedef NTSint<Edge::Node> NConv;
typedef LTSstr<Edge::Label> LConv;
typedef DOTWrapper<Edge, NConv, LConv> DOTf;
const DOTf dotf((NConv()), (LConv()));
typedef NTSint NConv;
类型定义LTSstr LConv;
typedef DOTf;
常量dotfdotf((NConv()),(LConv());
我明白了

错误:没有用于初始化的匹配构造函数 “const DOTf”(又名“const DOTWrapper”)的名称 const DOTf DOTf((NConv()),(LConv());”


为什么呢?NConv和LConv毕竟在内存中有一个位置。。。所以它们不应该是l值吗?

NConv
是一种类型,而不是对象。不,它没有“在内存中占有一席之地”。但是我不是在用
ncov()
创建这种类型的对象吗?是的,那又怎样?您正在创建一个临时对象,它是一个prvalue。啊,我以为对象总是l值。为什么对于我作为临时对象传递给某个函数的所有函数对象,我没有得到这个错误?类似于std::sort(),类似于
排序(obj1.begin()、obj1.end()、functionObjectType())那些没有可变的左值引用参数。