欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > C++编程指南37 - 使用 concept 限制模板参数类型

C++编程指南37 - 使用 concept 限制模板参数类型

2025/4/28 21:36:04 来源:https://blog.csdn.net/zg260/article/details/147402421  浏览:    关键词:C++编程指南37 - 使用 concept 限制模板参数类型

一 概述

        concept是C++20 引入的语言特性,concept 是一种用于约束模板参数的编译期布尔表达式(谓词),它描述了一个类型应该具有的某些性质(比如是否可比较、是否可拷贝、是否支持某种操作等)。

        在 C++20 之前,模板参数不受限制,任何类型都可以传进去,直到你在模板内部调用了不存在的函数或操作才爆炸式报错,比如这样:

template<typename T>
void print_size(const T& obj) {std::cout << obj.size() << '\n'; // 如果 T 没有 size(),编译器报个几十行的模板错误
}

        报错晦涩难懂,用户根本不知道为什么错,引入 Concept 之后,我们可以提前限制参数类型,并提供更清晰的错误信息: 

#include <concepts>template<typename T>
requires requires (T t) { t.size(); }
void print_size(const T& obj) {std::cout << obj.size() << '\n';
}

二:预定义concept和自定义concept 

       1.  C++20 提供了一组标准 concept:

    2. 自定义concept

假设定义一个 concept 要求类型 T 有一个 size() 成员函数,且能返回可以转换为 std::size_t 的值。 

template<typename T>
concept HasSize = requires(T t) {{ t.size() } -> std::convertible_to<std::size_t>;
};

我们可以这样使用它:

template<HasSize T>
void print_size(const T& t) {std::cout << t.size() << '\n';
}
template<typename T>
requires HasSize<T>
void print_size(const T& t) {std::cout << t.size() << '\n';
}

三:concept的例子(代替SFINAE)

        SFINAE(Substitution Failure Is Not An Error)是模板编程中一个重要的机制,当模板在替换(推导)类型时,如果出现非法代码,不会报错,而是自动忽略该模板实例化版本,去尝试别的重载或模板。

        下面举一个例子,写一个函数 increment(),只允许传入可以加一的类型(比如整数),不允许传入不支持 ++ 的类型(比如 std::string)。看下C++98/11/14/20 如何实现

       1. C++98 的实现(用SFINAE)

template<bool B, typename T = void>
struct enable_if {};template<typename T>
struct enable_if<true, T> {typedef T type;
};template<typename T>
struct is_integral {static const bool value = false;
};template<>
struct is_integral<int> {static const bool value = true;
};#include <iostream>template<typename T>
typename enable_if<is_integral<T>::value, T>::type
increment(T value) {return value + 1;
}

      2. C++11/14 的实现(用SFINAE)

#include <type_traits>
#include <iostream>template<typename T>
typename std::enable_if<std::is_integral<T>::value, T>::type
increment(T value) {return value + 1;
}

        3. C++20的实现 (用concept)

#include <concepts>
#include <iostream>template<std::integral T>
T increment(T value) {return value + 1;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词