C++ 在C+;中未计算为函数的术语+;

C++ 在C+;中未计算为函数的术语+;,c++,C++,我有以下代码,这些代码取自Boost,并为我的项目进行了简化。请接受我粘贴完整代码的建议,我这样做是为了方便回答我的问题。在VS2008中编译以下代码时,我遇到了以下错误 error C2064: term does not evaluate to a function taking 3 arguments 我期待addOptions retruns OptionsInit对象,它用三个参数调用函数运算符,但这并没有发生,任何一个都可以找到bug。提前谢谢 namespace MyInfras

我有以下代码,这些代码取自Boost,并为我的项目进行了简化。请接受我粘贴完整代码的建议,我这样做是为了方便回答我的问题。在VS2008中编译以下代码时,我遇到了以下错误

error C2064: term does not evaluate to a function taking 3 arguments
我期待addOptions retruns OptionsInit对象,它用三个参数调用函数运算符,但这并没有发生,任何一个都可以找到bug。提前谢谢

namespace MyInfrastructure
{
namespace Internal
{
    class OptionDescrp;
    class OptionsInit;
}

class OptionsCollection
{
public:

    OptionsCollection(std::string optCollName);
    Internal::OptionsInit addOptions();

private:

    // avoid copying and assignment.
    // Prohibit copy
    OptionsCollection( const OptionsCollection& );
    OptionsCollection& operator = (const OptionsCollection& );

    void add(Internal::OptionDescrp* desc) {m_options.push_back(desc);}

    std::vector<Internal::OptionDescrp* > m_options;
    std::string m_optCollName;

    friend class Internal::OptionsInit;
};
}

////////////

#include <string>
#include <vector>
#include <assert.h>
#include "PrgmOptions.h"


namespace MyInfrastructure
{
namespace Internal
{

class OptionDescrp 
{
public:

    OptionDescrp(std::string pcOptname, std::string description, bool isOptValueReq);
    virtual ~OptionDescrp(){ };

private:

    std::string m_shortName;  // option short name.
    std::string m_longName;   // option long name.
    std::string m_description;// option description.
};

class OptionsInit
{
public:
    OptionsInit(OptionsCollection* coll){ owner = coll; }
    OptionsInit& operator()(std::string name, std::string description, bool isOptValReq);

private:
    OptionsCollection* owner;
};

}

/////

namespace MyInfrastructure
{
    OptionsCollection::OptionsCollection(std::string optCollName) : m_optCollName(optCollName) {}

    Internal::OptionsInit OptionsCollection::addOptions()
    {       
        return Internal::OptionsInit(this);
    }
}

namespace MyInfrastructure
{
namespace Internal
{
    // Class Options description definitions.
    OptionDescrp::OptionDescrp(std::string pcOptname, std::string description, bool isOptValueReq)
                                : m_description(description)
    {
        std::string name(pcOptname);
        std::string::size_type n = name.find(',');
        if (n != std::string::npos) 
        {
            assert(n == name.size()-2);
            m_longName  = name.substr(0, n);
            m_shortName = '-' + name.substr(n+1,1);
        }
        else
        {
            m_longName = name;
        }
    }

    // Class Options Init definitions.
    OptionsInit& OptionsInit::operator()(std::string name, std::string description, bool isOptValReq)
    {
        OptionDescrp* opt = new OptionDescrp(name, description, isOptValReq);
        owner->add(opt);
        return *this;
    }
}
}

//////


int main(void)
{
    MyInfrastructure::OptionsCollection desc("myoptions");

    **desc.addOptions()("help", "produce help message", false); // error is thrown here**

  return 0;
}
名称空间MyInfrastructure
{
命名空间内部
{
类别选择SCRP;
类选项初始化;
}
类选项集合
{
公众:
optionCollection(std::string optCollName);
内部::选项init addOptions();
私人:
//避免复制和分配。
//禁止复制
选项集合(常量选项集合&);
optionCollection&运算符=(const optionCollection&);
void add(内部::OptionDescrp*desc){m_options.push_back(desc);}
std::向量m_选项;
std::字符串m_optCollName;
好友类内部::OptionsInit;
};
}
////////////
#包括
#包括
#包括
#包括“PrgmOptions.h”
命名空间MyInfrastructure
{
命名空间内部
{
类别选项SCRP
{
公众:
OptionDescrp(标准::字符串pcOptname,标准::字符串描述,bool isOptValueReq);
虚拟~OptionDescrp(){};
私人:
std::string m_shortName;//选项shortName。
std::string m_longName;//选项long name。
std::string m_description;//选项描述。
};
类选项初始化
{
公众:
OptionsInit(optionCollection*coll){owner=coll;}
OptionsInit&operator()(std::string name,std::string description,bool isOptValReq);
私人:
选择集合*所有者;
};
}
/////
命名空间MyInfrastructure
{
optionCollection::optionCollection(std::string optCollName):m_optCollName(optCollName){}
内部::选项初始化选项集合::添加选项()
{       
返回内部::OptionsInit(this);
}
}
命名空间MyInfrastructure
{
命名空间内部
{
//类选项描述定义。
OptionDescrp::OptionDescrp(标准::字符串pcOptname,标准::字符串描述,布尔等值请求)
:m_说明(说明)
{
std::字符串名称(pcOptname);
std::string::size_type n=name.find(',');
if(n!=std::string::npos)
{
断言(n==name.size()-2);
m_longName=name.substr(0,n);
m_shortName='-'+name.substr(n+1,1);
}
其他的
{
m_longName=名称;
}
}
//类选项初始化定义。
OptionsInit&OptionsInit::operator()(std::string name,std::string description,bool isOptValReq)
{
OptionDescrp*opt=新OptionDescrp(名称、说明、isOptValReq);
所有者->添加(选择);
归还*这个;
}
}
}
//////
内部主(空)
{
MyInfrastructure::OptionCollection desc(“myoptions”);
**desc.addOptions()(“帮助”,“生成帮助消息”,false);//此处抛出错误**
返回0;
}

有趣的代码:addOptions()返回的OptionsInit是一个临时的。然后,您对它调用一个非常量方法,这是允许的,但它返回一个对自身的非常量引用,这也是允许的,因为它是一个非常量方法。但这实际上意味着您将一个非常量引用“后门”绑定到一个临时

我假设desc.addOptions前面的两个星号实际上不在代码中,因为这里没有重载运算符*


也许,如果您将operator()设为const并返回const引用,它就会工作。

有趣的代码:OptionsInit由addOptions()返回是临时的。然后对其调用一个非常量方法,这是允许的,但它返回一个对自身的非常量引用,这也是允许的,因为它是一个非常量方法。但这意味着本质上是将非常量引用绑定到临时

我假设desc.addOptions前面的两个星号实际上不在代码中,因为这里没有重载运算符*


也许如果您将operator()设为const并返回const reference,它就会工作。

当我们将所有内容复制到单个文件中时,问题中的示例代码使用Visual 2008、gcc和Visual 2003编译时不会出错。 出现错误C2064,可能是因为在其他标题中有一个#define或另一个定义没有包含在示例中,或者您没有完全编译示例代码。
尝试将所有示例代码复制到一个文件中并进行编译。

当我们将所有示例代码复制到一个文件中时,问题中的示例代码使用Visual 2008、gcc和Visual 2003进行编译,没有错误。 出现错误C2064,可能是因为在其他标题中有一个#define或另一个定义没有包含在示例中,或者您没有完全编译示例代码。
尝试将所有示例代码复制到一个文件中并编译。

问题在于VS2008。我用VS2010编译,它编译得很好。感谢所有的输入。

问题在于VS2008。我用VS2010编译,它编译得很好。感谢所有的输入。

您的代码示例不完整-您在“//行;在修复该问题并在开头添加#include#include后,代码在MSVC2008中编译良好(2009版本不存在)和GCC。首先,错误消息无疑带有行号,但我没有看到指示的行。请指出哪一行出现了错误。另外,你写的是VS 2009。你的意思是VS 2008吗?我仍然收到错误,我使用的是VS2008I,我得到的结果与@zeuxcg相同——在添加了一个右括号之后,所以你不想定义一个右括号她的MyInfrastructure在MyInfrastructure内部,它编译得很好。我的第一个想法是,也许你需要将SP1应用到你的VC++副本中?我将这些代码放在不同的文件中,粘贴在这里时我粘贴了