C++20概念模板报错:函数模板无匹配实例(参数类型不符)
C++20 Concept模板函数调用错误分析与解决
定义的Concept与模板函数
template<typename T> concept Averageable = std::is_default_constructible<T>::value && requires(T a, T b) { { a += b } -> std::convertible_to<T>; {a / size_t(1)} -> std::convertible_to<T>; }; template<typename T> requires Averageable<T> T mean(const T* vals, size_t size) { T sum(); for (size_t i{}; i < size; size++) { sum += vals[i]; } return sum / size; }
调用代码
const int a[]{1,2,3}; const int res = mean<int>(a, 3);
错误信息
no instance of function template matches the argument list argument types are: (size_t, int)
问题原因
- Concept约束不满足:对于
int类型,a / size_t(1)的运算结果是size_t类型(算术运算会进行类型提升,int会被转换为无符号的size_t),而size_t无法隐式转换为int,不满足std::convertible_to<T>的要求,因此int不符合Averageable概念,模板函数无法匹配。 - 函数内语法逻辑错误:
T sum();这是声明了一个返回T类型的函数sum,而非创建默认构造的T类型对象,导致后续sum += vals[i]操作非法。- 循环内的
size++是错误的,应该是i++,否则循环条件i < size永远成立,会陷入死循环且逻辑完全错误。
解决方法
1. 修复Concept约束
调整除法运算的约束逻辑,确保运算结果能转换为T类型。可以将除数转为T类型,避免类型提升导致的不匹配:
template<typename T> concept Averageable = std::is_default_constructible_v<T> && requires(T a, T b) { { a += b } -> std::convertible_to<T>; { a / T(1) } -> std::convertible_to<T>; // 用T类型的除数,保证结果类型为T };
2. 修复模板函数内的错误
修正对象初始化和循环变量的问题,同时将除法的size转为T类型,避免类型不匹配:
template<typename T> requires Averageable<T> T mean(const T* vals, size_t size) { T sum{}; // 默认构造T类型对象,而非函数声明 for (size_t i{}; i < size; i++) // 用i++遍历数组元素 { sum += vals[i]; } return sum / static_cast<T>(size); // 将size转为T类型再做除法 }
调整后的完整可运行代码
#include <concepts> #include <type_traits> template<typename T> concept Averageable = std::is_default_constructible_v<T> && requires(T a, T b) { { a += b } -> std::convertible_to<T>; { a / T(1) } -> std::convertible_to<T>; }; template<typename T> requires Averageable<T> T mean(const T* vals, size_t size) { T sum{}; for (size_t i{}; i < size; ++i) { sum += vals[i]; } return sum / static_cast<T>(size); } int main() { const int a[]{1,2,3}; const int res = mean<int>(a, 3); // 可正常编译运行 return 0; }
内容的提问来源于stack exchange,提问作者Devin M
相关产品推荐
相关产品推荐

