Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将匿名临时函数对象传递给模板化构造函数时出现问题_C++_Templates_Anonymous_Functor - Fatal编程技术网

C++ 将匿名临时函数对象传递给模板化构造函数时出现问题

C++ 将匿名临时函数对象传递给模板化构造函数时出现问题,c++,templates,anonymous,functor,C++,Templates,Anonymous,Functor,我试图附加一个函数对象,以便在销毁模板化类时调用它。但是,我似乎无法将函数对象作为临时对象传递。我得到的警告是(如果注释行xi.data=5;): 我为这段冗长的代码感到抱歉,但我认为所有组件都需要可见才能评估情况 template<typename T> struct Base { virtual void run( T& ){} virtual ~Base(){} }; template<typename T, typename D> str

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

我为这段冗长的代码感到抱歉,但我认为所有组件都需要可见才能评估情况

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;
};
模板
结构基
{
虚拟空运行(T&){}
虚拟~Base(){}
};
模板
结构派生:公共基
{
虚拟无效运行(T&T)
{
D;
d(t);
}
};
模板
结构X
{
模板
X(常数R&R)
{

std::cout在
xxi2((writer())周围尝试一对额外的括号;
这将阻止编译器认为您预先声明了一个函数。(Scott Meyers有效STL项6。)

看起来像是一个“最麻烦的解析”问题。试试看

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

xxi2((writer());
X xi2(writer());
是一个名为xi2的函数的声明,它本身返回一个
X
,并将一个不带参数但返回writer的函数作为参数。这是一个“最麻烦的解析”


解决方案是要么做你已经做过的事情,避免临时的,要么添加更多的括号。

共享的
shared\u ptr
的实现使用相同的东西(用于删除),所以它是可行的!您需要一个自定义的复制构造函数和赋值运算符来处理内存…所以最好使类型也可克隆。有趣的是,我想不出一种方法让我的函数对象保持状态,只能在删除时使用默认构造的函数对象。是的,我有一个复制构造函数和assignment运算符,但从代码中删除了它们以使其更“美观”:。谢谢!这两个都很好!但遗憾的是,“在需要时”使用函数对象的美妙之处丢失了(或者需要额外的括号或显式调用构造函数)。谢谢!(哦!我从来没有听说过“最麻烦的解析”,因此这是新的:)@Tyler McHenry值得注意的是,第一个示例在类为
不可复制的情况下不起作用,因为它执行类的复制构造函数。
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;
};
X<int> xi2 = X<int>(writer());
X<int> xi2((writer()));