当前位置: 首页 > 知识库问答 >
问题:

无临时实例的参数转发

柏夕
2023-03-14

我有一个模板类,它包装了一个名为mObject的std::向量。

类有一个insert函数,它转发MyArray实例中实际存储的类型的参数(我认为它称为可变模板参数)。在本例中,我存储MyMesh类型,但它可以是任何类型。

正如您在main()函数中看到的,mObject向量不会增长,它的元素会被一次又一次地覆盖。

考虑对象池类型的数据结构。

一切正常。

template <class T>
class MyArray
{
    public:

        MyArray(const int capacity) :
            mObjects(capacity)
        {
            mNextIndex = 0;
        }

        template <typename... Args>
        void insert(Args&&... args)
        {

            mObjects[mNextIndex] = T{ std::forward<Args>(args)... };    //PROBLEMATIC ASSIGNMENT

            //... not relevant code
        }

    private:

        int             mNextIndex;
        std::vector<T>  mObjects;

};



int main()
{
    MyArray<Mesh> sa(2);

    sa.insert("foo",1111);  //goes to mObjects[0]
    sa.insert("bar",2222);  //goes to mObjects[1], and tada, the vector is full

    sa.remove(1111);    //not implemented above, but not relevant. Remove func basically adjusts mNextIndex, so mObjects[0] will be overwritten upon next insert.

    sa.insert("xxx",3333);  //mObjects[0] gets overwritten from "foo" to "xxx" and 1111 to 3333
}

我的问题是上面的一行被注释为//有问题的作业。

mObjects[mNextIndex] = T{ std::forward<Args>(args)... };

当该命令执行时,会发生3种情况:

>

  • 调用MyMesh(const string s,int x)构造函数,这意味着在这里的堆栈上分配整个MyMesh。为什么?我只想将转发的参数传递给现有的mObjects[mNextIndex]元素。

    运算符=(MyMesh

    ~cVMesh()的调用意味着临时变量释放并消亡。

    我想摆脱#1和#3。所以不想要“昂贵”的临时对象创建。我只想将传入的MyMesh参数转发/分配给mObject[mNextIndex]。类似于std::vector.emplace_back()所做的,但指向mNextIndex指向的任何位置。

    如何只将参数转发给C中的现有变量,而不实例化临时变量?

    为了实现完整性,这里是存储在MyArray类中的MyMesh类。调用构造函数/析构函数/赋值运算符时,只打印一些消息,没有什么特别之处:

    class Mesh
    {
    public:
        Mesh()
        {
            cout << "Mesh()" << std::endl;
            mStr = "";
            mId = 99999999;
        }
        Mesh(const string s, int x)
        {
            cout << "Mesh(const string s, int x)" << std::endl;
            mStr = s;
            mId = x;
        }
        ~Mesh()
        {
            cout << "~Mesh()" << std::endl;
        }
        Mesh& operator=(const Mesh& other)
        {
            cout << "operator=(const Mesh& other)" << std::endl;
            cout << mStr << " becomes " << other.mStr << endl;
            cout << mId << " becomes " << other.mId << endl;
            mStr = other.mStr;
            mId = other.mId;
            return *this;
        }
        Mesh& operator=(Mesh&& other) noexcept
        {
            cout << "operator=(Mesh&& other)" << std::endl;
            cout << mStr << " becomes " << other.mStr << endl;
            cout << mId << " becomes " << other.mId << endl;
            mStr = other.mStr;
            mId = other.mId;
            return *this;
        }
        Mesh(const Mesh& other)
        {
            cout << "Mesh(const Mesh& other)" << std::endl;
            mStr = other.mStr;
            mId= other.mId;
        }
        Mesh(Mesh&& other) noexcept
        {
            cout << "Mesh(Mesh&& other)" << std::endl;
            mStr = other.mStr;
            mId = other.mId;
            other.mStr = "";
            other.mId = 99999999;
        }
    
        string mStr;
        int mId;
    
    };
    
  • 共有3个答案

    农鸿达
    2023-03-14

    您可以添加:

    void assign(const string& s, int x)
    {
        cout << "assign(const string s, int x)" << std::endl;
        mStr = s;
        mId = x;
    }
    

    并使用它:

    mObjects[mNextIndex].assign(std::forward<Args>(args)...);
    
    方祺
    2023-03-14

    mObject[mNextIndex]=T{std::forward

    整个MyArray类非常无用,因为vector已经具有类似的功能。

    vector<Mesh> sa;
    sa.reserve(2);
    sa.emplace_back("foo",1111); // Mesh constructor called once
    sa.emplace_back("bar",2222); // Mesh constructor called once again
    

    洪俊拔
    2023-03-14

    我想你想要的是用新的值重建向量中的任意元素

    #include<vector>
    
    template<class T, class... Args>
    void create_at_nth_place(std::vector<T>& v, int n, Args&&...args){
        auto& elem = v[n];
        elem.~T();
        new(&elem) T(std::forward<Args>(args)...);
    }
    
    struct S {
        S();
        S(int, bool);
        template<class... Args>
        S(Args&&...);
        S(S&&) noexcept;
        ~S();
    };
    
    void f() {
        std::vector<S> v(3);
        create_at_nth_place(v, 2, 4323, false);
        char a = 'a';
        create_at_nth_place(v, 2, 'a', 123, 1232, 32.f, a);
    }
    

    链接:https://godbolt.org/g/3K9akZ

     类似资料:
    • 问题内容: 我想知道如何/是否有可能删除所有临时表的查询? 我一直在尝试使用tempdb.sys.tables解决问题,但是正在努力格式化name列使其可以被删除- 另一个使事情变得棘手的因素是,temp表名称通常包含’_’意味着进行替换变得更麻烦了(至少对我而言!) 有什么我可以使用的方法,可以删除所有临时表(本地或全局),而不必分别删除所有临时表? 谢谢! 问题答案: 临时表的要点是它们是..

    • 本文向大家介绍SpringMVC的@InitBinder参数转换代码实例,包括了SpringMVC的@InitBinder参数转换代码实例的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要介绍了SpringMVC的@InitBinder参数转换代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 以上就是本文的全部内容,希望对大家的学习有所

    • 本文向大家介绍oracle 临时表详解及实例,包括了oracle 临时表详解及实例的使用技巧和注意事项,需要的朋友参考一下 在Oracle8i或以上版本中,可以创建以下两种临时表: 1。会话特有的临时表 CREATE GLOBAL TEMPORARY <TABLE_NAME> ( <column specification> ) ON COMMIT PRESERVE ROWS;  2。事务特有的临

    • 当我尝试使用hibernate postgresql获取列表时,我收到以下错误 MyObject: 用户: 首先,我获取用户并将其保存在用户对象中: 然后,当我试图通过用户获取MyObject的列表时: 我收到 我做错了什么?

    • 我有两个模型类,用户和问候如下。用户表中的外键(称呼_id)是可选的。为了在合并后立即刷新会话对象时保存用户对象,我得到以下错误信息。 对象引用未保存的临时实例-在刷新之前保存临时实例:com。实例模型打招呼 表中的数据称呼已经独立于用户表插入。当我试图保存salutation_id为空的用户对象时,它会抛出这个错误。 任何帮助都是值得的。 谢谢你的帮助。

    • 我们正在开发一个连接到遗留数据库的应用程序。这是非常“非类型化”的,几乎所有数据都使用字符串。更糟糕的是,这远远不是同质的:它使用不同的日期或时间模式(“YYDDMM”、“HHMMSS”、毫秒)和布尔值模式(“Y”/“N”、“X'/' '), 例如。 我们想使用JPA(EclipseLink)和定制转换器。问题是需要一个实现的类,因此我们必须为每个模式创建新的类。我想要的是一个BooleanCon