【问题标题】:Problems with passing an anonymous temporary function-object to a templatized constructor将匿名临时函数对象传递给模板化构造函数的问题
【发布时间】:2010-04-06 13:15:28
【问题描述】:

我正在尝试附加一个函数对象,以便在销毁模板化类时调用。但是,我似乎无法将函数对象作为临时对象传递。我得到的警告是(如果注释行xi.data = 5;):

    warning C4930: 'X<T> xi2(writer (__cdecl *)(void))': 
    prototyped function not called (was a variable definition intended?)
            with
            [
                T=int
            ]

如果我尝试使用构造的对象,我会得到一个编译错误:

error C2228: left of '.data' must have class/struct/union

对于这段冗长的代码,我深表歉意,但我认为所有组件都需要可见才能评估情况。

template<typename T>
struct Base
{
    virtual void run( T& ){}
    virtual ~Base(){}
};

template<typename T, typename D>
struct Derived : public Base<T>
{
    virtual void run( T& t )
    {
        D d;
        d(t);
    }
};

template<typename T>
struct X
{
    template<typename R>
    X(const R& r)
    {
       std::cout << "X(R)" << std::endl;
       ptr = new Derived<T,R>(); 
    }

    X():ptr(0)
    { 
        std::cout << "X()" << std::endl; 
    }

    ~X()
    {
        if(ptr) 
        {
            ptr->run(data);
            delete ptr;
        }
        else
        {
            std::cout << "no ptr" << std::endl;
        }
    }

    Base<T>* ptr; 
    T data;
};

struct writer
{
    template<typename T>
    void operator()( const T& i )
    { 
        std::cout << "T : " << i << std::endl;
    }
};

int main()
{
    {
        writer w;
        X<int> xi2(w);
        //X<int> xi2(writer()); //This does not work!
        xi2.data = 15;       
    }

    return 0;
};

我尝试这样做的原因是,我可以“以某种方式”将函数对象类型与对象附加在一起,而无需在类中保留函数对象本身的实例。因此,当我创建class X 的对象时,我不必在其中保留class writer 的对象,而只需在其中保留一个指向Base&lt;T&gt; 的指针(我不确定是否需要&lt;T&gt;,但是现在它在那里)。

问题是我似乎必须创建一个writer 的对象,然后将其传递给X 的构造函数,而不是像X&lt;int&gt; xi(writer(); 那样调用它

我可能在这里遗漏了一些完全愚蠢和明显的东西,有什么建议吗?

【问题讨论】:

  • shared_ptr的实现使用了同样的东西(用于删除),所以是可行的!你需要一个自定义的复制构造函数和赋值运算符来处理内存......所以最好让类型也可克隆。
  • 有趣的是,我想不出我的函数对象保持状态的方法,只能在删除时使用默认构造的函数对象。是的,我确实有一个复制构造函数和赋值运算符,但是从这里的代码中删除了它们以使其更“像样”:)。谢谢!

标签: c++ templates anonymous functor


【解决方案1】:

看起来像一个“最令人头疼的解析”问题。试试

X<int> xi2 = X<int>(writer());

X<int> xi2((writer()));

【讨论】:

  • 很好,这两项工作!但遗憾的是,“在需要时”使用函数对象的美感消失了(或者需要额外的括号或对构造函数的显式调用)。谢谢! (哦!我从未听说过“最令人烦恼的解析”,所以这是新的:))
  • @Tyler McHenry Worth 注意到第一个示例在类为 noncopyable 的情况下不起作用,因为它执行类的复制构造函数。
【解决方案2】:

X&lt;int&gt; xi2(writer()); 是一个名为 xi2 的函数的声明,它本身返回一个 X&lt;int&gt;,并将一个不带参数并返回一个 writer 的函数作为参数。这是一个“最令人头疼的解析”。

解决方案是要么做你所做的,避免临时的,要么添加更多的括号。

【讨论】:

    【解决方案3】:

    尝试在X&lt;int&gt; xi2((writer())); 周围多加一对括号,这将阻止编译器认为您预先声明了一个函数。 (Scott Meyers 有效的 STL 项目 6。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-09
      • 1970-01-01
      • 1970-01-01
      • 2013-07-10
      • 1970-01-01
      • 2011-10-24
      • 2018-10-31
      • 1970-01-01
      相关资源
      最近更新 更多