C++ 例外安全保证和std::move()

C++ 例外安全保证和std::move(),c++,c++11,exception-safety,C++,C++11,Exception Safety,在一些实现过程中,我遇到了异常安全保证和使用std::move()的问题。我知道SO不是一个问“你的意见是什么”(类模板Boo)这类问题的好地方,但在这里,我想确定我的理解是否正确,在你阅读这个问题后,也许你可以指导我找到正确的路径 考虑以下代码: struct Foo { using Y = std::vector<std::string>; using X = std::vector<Y>; void add (Y y) {

在一些实现过程中,我遇到了异常安全保证和使用
std::move()
的问题。我知道SO不是一个问“你的意见是什么”(类模板
Boo
)这类问题的好地方,但在这里,我想确定我的理解是否正确,在你阅读这个问题后,也许你可以指导我找到正确的路径

考虑以下代码:

struct Foo {
    using Y = std::vector<std::string>;
    using X = std::vector<Y>;

    void add (Y y) {
        src.push_back (std::move (y));      // (1)
        src = process (std::move (src));    // (2)         
    }

private:
    X process (X&& vec) {                   // (F)
        for (auto& v : vec) {
            v.resize (10);                  // (3)
        }
        return std::move (vec);
    }


    X src;
};
?

因此,如果
Foo::src
有大量元素,那么 担保与较低的效率相关(因为必须制作额外的副本)

也许保证级别应该由类的用户决定,将其设置为类模板,如下所示:

struct S {};
struct B {};

template <typename T>
struct Boo {
    using Y = std::vector<std::string>;
    using X = std::vector<Y>;

    void add (Y y) {
        src.push_back (std::move (y));
        src = process_helper (typename std::is_same<T, S>::type {});
    }


private:
    X process_helper (std::true_type) {
        return process (src);
    }

    X process_helper (std::false_type) {
        return process (std::move (src));
    }

    X process (X vec) {
        for (auto& v : vec) {
            v.resize (10);                  
        }
        return std::move (vec);
    }

    X src;
};
struct S{};
结构B{};
模板
结构Boo{
使用Y=std::vector;
使用X=std::vector;
无效添加(Y){
src.push_back(标准::移动(y));
src=process\u helper(typename std::is\u same::type{});
}
私人:
X进程\u助手(标准::真\u类型){
返回过程(src);
}
X进程\u助手(标准::假\u类型){
返回过程(std::move(src));
}
X过程(X向量){
用于(自动&v:vec){
v、 调整大小(10);
}
返回标准::移动(vec);
}
X src;
};

这是个好主意还是坏主意?

process
间接地做
src=std::move(src)
@nwp:我不这么认为:它首先移动构造一个临时的。为什么不
X进程(X&&vec_-in){auto vec=std::move(vec_-in);
,或者干脆
X进程(X-vec)
?啊,因为这个调用去掉了你的src。真的要修复它,你需要
src.push_back(std::move(y));
在插入之前“处理”
y
,或者跟踪如何反转所有内容(不使用异常检查来减少开销)?@Yakk我没有提到
resize()背后的全部想法
调用,因为我认为它不值得,但是如果您建议在插入之前处理
y
,我不得不担心您(或我),我不能这样做,因为我希望所有
src
行的长度完全相同,这意味着如果我通过
y
,其中有不同(更大)的行大小比
src
中的任何行都大,然后我必须采取措施调整其余行的大小,以保持它们相等(等于y)。异常后恢复仍然是一种选择。就个人而言:只要您不是在编写通用库,我就会仔细查看调用代码,看看它是否需要强异常保证,并相应地决定是否使用一种变体。特别是,应用程序在r aStd::抛出错误的\u alloc。
struct S {};
struct B {};

template <typename T>
struct Boo {
    using Y = std::vector<std::string>;
    using X = std::vector<Y>;

    void add (Y y) {
        src.push_back (std::move (y));
        src = process_helper (typename std::is_same<T, S>::type {});
    }


private:
    X process_helper (std::true_type) {
        return process (src);
    }

    X process_helper (std::false_type) {
        return process (std::move (src));
    }

    X process (X vec) {
        for (auto& v : vec) {
            v.resize (10);                  
        }
        return std::move (vec);
    }

    X src;
};