我可以直接调用operator()而无需创建临时对象吗?

时间:2013-05-04 18:22:15

标签: c++ boost stl

我有以下实用程序函数将给定字符串转换为整数。

class convertToInt:public std::unary_function<const char*, int>
{

        public:
                int operator()(const char* cNumber)
                {
                        try
                        {
                                int result = boost::lexical_cast<int>(cNumber);
                                return result;
                        } catch ( boost::bad_lexical_cast& error)
                        {
                                std::cerr << "Error in converting to number "<< error.what() << std::endl;
                                return -1;
                        }
                }

};

当我想要实际使用此实用程序功能时,我将执行以下操作。

  convertToInt cStrToInt;
  int iNumberToCheck = cStrToInt(argv[1]);

我只是想知道,有没有办法,我可以直接打电话

int iNumberToCheck = convertToInt(argv[1]);

5 个答案:

答案 0 :(得分:5)

不,它是一个成员函数,需要一个对象来调用它。您可以使用未命名的临时代码:

int iNumberToCheck = convertToInt()(argv[1]);

答案 1 :(得分:1)

您可以将该函数设置为静态,以便它不需要实例。电话必须是范围。

您还可以将临时文件创建为较大表达式的一部分(而不是使用命名变量),这可能看起来效率较低,但在实践中可能会被编译器对同一事物进行优化。

编辑添加:static不适用于operator(),因此您需要返工才能使用该选项。

答案 2 :(得分:1)

如果您知道呼叫站点处的仿函数的名称,那么您为什么不将其转换为函数呢?

int convertToInt(const char* cNumber)
{
    /*...*/
}

int iNumberToCheck = convertToInt(argv[1]);

答案 3 :(得分:1)

只需创建一个静态初始化的全局变量,这有助于避免the static initialization order fiasco。静态初始化要求类是聚合类型。只需使用大括号进行初始化:

struct convertToIntF
{
    int operator()(const char* cNumber) const
    {
        try
        {
            int result = boost::lexical_cast<int>(cNumber);
            return result;
        } 
        catch ( boost::bad_lexical_cast& error)
        {
            std::cerr << "Error in converting to number "<< error.what() << std::endl;
            return -1;
        }
    }
};

convetToIntF converToInt = {};

现在,如果函数对象存储状态或继承自非聚合的类,则不起作用。但是,在C ++ 11中,编写一个可以静态初始化任何默认构造函数对象的适配器是相当简单的:

template<class F>
struct static_
{
    template<class... T>
    auto operator()(T && ... x) const -> decltype(F()(std::forward<T>(x)...))
    {
        static F f;
        return f(std::forward<T>(x)...);
    }
};

然后可以像这样初始化:

static_<convetToIntF> converToInt = {};

答案 4 :(得分:0)

在这个非常简单的案例中,匿名对象可能会正常工作,正如其他人指出的那样。但是,如果你有一个更复杂的状态类,请考虑单例模式:

class SingletonFunctor
{
    private:

        // some private state

        // for a hybrid approach, the constructor could be public
        SingletonFunctor()
        {
            // initialize state
        }

     public:

        static const SingletonFunctor& GetSingleton()
        {
            static const SingletonFunctor _singleton;

            return _singleton;
        }

        SomeType operator() (SomeOtherType param) const
        {
            // do something interesting
        }            
};

int main (void)
{
    SomeType firstVal = SingletonFunctor::GetSingleton()(SomeOtherType());

    // ...
    // later

    // no need to instantiate another object
    SomeType secondVal = SingletonFunctor::GetSingleton()(SomeOtherType());
}

如果改变状态,请小心这种模式,然后它可能会遇到与全局变量相同的问题(尤其是多线程)。