Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/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++;使用带有不变量的函数预条件或包装类?_C++_Design Patterns_Wrapper_Assertions_Invariants - Fatal编程技术网

C++ C++;使用带有不变量的函数预条件或包装类?

C++ C++;使用带有不变量的函数预条件或包装类?,c++,design-patterns,wrapper,assertions,invariants,C++,Design Patterns,Wrapper,Assertions,Invariants,我发现自己编写了很多函数,这些函数都是从许多前提条件开始的,然后我必须弄清楚如何处理所有无效输入,并为它们编写测试 请注意,我使用的代码库不允许抛出异常,以防异常与此问题相关 我想知道是否有C++设计模式,而不是有前提条件,输入参数是通过保证不变量的包装类传递的。例如,假设我想要一个函数返回整数向量中的最大值。通常我会这样做: // Return value indicates failure. int MaxValue(const std::vector<int>& vec

我发现自己编写了很多函数,这些函数都是从许多前提条件开始的,然后我必须弄清楚如何处理所有无效输入,并为它们编写测试

请注意,我使用的代码库不允许抛出异常,以防异常与此问题相关

我想知道是否有C++设计模式,而不是有前提条件,输入参数是通过保证不变量的包装类传递的。例如,假设我想要一个函数返回整数向量中的最大值。通常我会这样做:

// Return value indicates failure.
int MaxValue(const std::vector<int>& vec, int* max_value) {
    if (vec.empty()) {
        return EXIT_FAILURE;
    }
    *max_value = vec[0];
    for (int element : vec) {
        if (element > *max_value) {
            *max_value = element;
        }
    }
    return EXIT_SUCCESS;
}
template <class T>
class NonEmptyVectorWrapper {
  public:
    static std::unique_ptr<NonEmptyVectorWrapper>
             Create(const std::vector<T>& non_empty_vector) {
        if (non_empty_vector.empty()) {
             return std::unique_ptr<NonEmptyVectorWrapper>(nullptr);
        }
        return std::unique_ptr<NonEmptyVectorWrapper>(
            new NonEmptyVectorWrapper(non_empty_vector));
    }

    const std::vector<T>& vector() const {
        return non_empty_vector_;
    }

  private:
    // Could implement move constructor/factory for efficiency.
    NonEmptyVectorWrapper(const std::vector<T>& non_empty_vector)
            : non_empty_vector_(non_empty_vector) {}
    const std::vector<T> non_empty_vector_;
};

int MaxValue(const NonEmptyVectorWrapper<int>& vec_wrapper) {
    const std::vector<int>& non_empty_vec = vec_wrapper.vector();
    int max_value = non_empty_vec[0];
    for (int element : non_empty_vec) {
        if (element > max_value) {
            max_value = element;
        }
    }
    return max_value;
}
//返回值表示失败。
int最大值(常量标准::向量和向量,int*max_值){
if(vec.empty()){
返回退出失败;
}
*最大值=向量[0];
for(int元素:vec){
如果(元素>*最大值){
*最大值=元素;
}
}
返回退出成功;
}
但我想知道是否有这样的设计模式:

// Return value indicates failure.
int MaxValue(const std::vector<int>& vec, int* max_value) {
    if (vec.empty()) {
        return EXIT_FAILURE;
    }
    *max_value = vec[0];
    for (int element : vec) {
        if (element > *max_value) {
            *max_value = element;
        }
    }
    return EXIT_SUCCESS;
}
template <class T>
class NonEmptyVectorWrapper {
  public:
    static std::unique_ptr<NonEmptyVectorWrapper>
             Create(const std::vector<T>& non_empty_vector) {
        if (non_empty_vector.empty()) {
             return std::unique_ptr<NonEmptyVectorWrapper>(nullptr);
        }
        return std::unique_ptr<NonEmptyVectorWrapper>(
            new NonEmptyVectorWrapper(non_empty_vector));
    }

    const std::vector<T>& vector() const {
        return non_empty_vector_;
    }

  private:
    // Could implement move constructor/factory for efficiency.
    NonEmptyVectorWrapper(const std::vector<T>& non_empty_vector)
            : non_empty_vector_(non_empty_vector) {}
    const std::vector<T> non_empty_vector_;
};

int MaxValue(const NonEmptyVectorWrapper<int>& vec_wrapper) {
    const std::vector<int>& non_empty_vec = vec_wrapper.vector();
    int max_value = non_empty_vec[0];
    for (int element : non_empty_vec) {
        if (element > max_value) {
            max_value = element;
        }
    }
    return max_value;
}
模板
类NonEmptyVectorWrapper{
公众:
静态标准::唯一\u ptr
创建(常量标准::向量和非空向量){
if(非空向量.empty()){
返回std::unique_ptr(nullptr);
}
返回std::unique\u ptr(
新的非空向量包装器(非空向量);
}
常量std::vector和vector()常量{
返回非空向量;
}
私人:
//可以实施移动建造商/工厂以提高效率。
NoneEmptyVectorWrapper(const std::vector和non_empty_vector)
:非空向量(非空向量){}
常数std::向量非空向量;
};
int MaxValue(常量非空向量包装器和向量包装器){
const std::vector&non_empty_vec=vec_wrapper.vector();
int max_value=非空向量[0];
for(int元素:非空向量){
如果(元素>最大值){
最大值=元素;
}
}
返回最大值;
}
这里的主要优点是避免了函数中不必要的错误处理。这是一个更复杂的示例,其中可能有用:

// Finds the value in maybe_empty_vec which is closest to integer n.
// Return value indicates failure.
int GetValueClosestToInt(
    const std::vector<int>& maybe_empty_vec,
    int n,
    int* closest_val);

std::vector<int> vector = GetRandomNonEmptyVector();
for (int i = 0; i < 10000; i++) {
    int closest_val;
    int success = GetValueClosestToInt(vector, i, &closest_val);
    if (success) {
        std::cout << closest_val;
    } else {
        // This never happens but we should handle it.
    }
}
//在maybe\u empty\u vec中查找最接近整数n的值。
//返回值表示失败。
int GetValueClosestToInt(
const std::vector&可能是空的,
int n,
整数*最近值);
std::vector vector=GetRandomNonEmptyVector();
对于(int i=0;i<10000;i++){
int最近值;
int success=GetValueClosestToInt(向量、i和最近值);
如果(成功){

std::难道我不明白“不能失败”是什么意思吗?你正在为你的包装器创建一个唯一的\u ptr,它实际上可以生成一个nullptr,因此取消引用它可以取消nullptr,它将终止(segfault或类似)。也就是说,你的调用者将取消包装器和segfault。这更好吗?或者我在这里遗漏了什么?