C++20中std::convertible_to概念使用报错,求排查原因
关于C++20 Concepts约束数字拼接函数的错误排查
问题描述
刚接触C++20 Concepts,想要实现一个将数字拼接为字符串的函数模板,尝试用std::convertible_to检查输入类型(此处为int)是否可转换为std::string,但运行时报错。相关代码及错误信息如下:
代码
//building the concept template <typename T> concept ConvertibleToStdString = std::convertible_to<T,std::string>; //using the concept template <ConvertibleToStdString T> std::string concatenate(T a, T b){ return std::to_string(a) + std::to_string(b); } int main(){ int x{623}; int y{73}; auto result = concatenate(x,y); std::cout << result << std::endl; return 0; }
错误信息
main.cpp:21:34: error: use of function 'std::string concatenate(T, T) [with T = int; std::string = std::basic_string<char>]' with unsatisfied constraints 21 | auto result = concatenate(x,y);
错误原因
你使用的std::convertible_to<T, std::string>约束不满足int类型,因为int并没有直接转换为std::string的路径:std::string没有接受int的构造函数,也没有从int到std::string的隐式/显式转换规则。代码里用到的std::to_string是标准库提供的重载函数,专门处理数字类型转字符串,但这不属于类型转换范畴,因此Concept的约束判定不通过。
修正方案
方案1:检查std::to_string是否可用
直接用requires表达式验证std::to_string对目标类型是否合法,匹配代码的实际逻辑:
#include <string> #include <iostream> template <typename T> concept ToStringable = requires(T t) { std::to_string(t); }; template <ToStringable T> std::string concatenate(T a, T b){ return std::to_string(a) + std::to_string(b); } int main(){ int x{623}; int y{73}; auto result = concatenate(x,y); std::cout << result << std::endl; return 0; }
方案2:兼容多种字符串转换场景
如果需要同时支持可以直接转换为std::string的类型(比如std::string本身、const char*)和需要std::to_string的数字类型,可以扩展Concept:
#include <string> #include <iostream> #include <concepts> template <typename T> concept StringConvertible = std::convertible_to<T, std::string> || requires(T t) { std::to_string(t); }; template <StringConvertible T> std::string concatenate(T a, T b){ if constexpr (std::convertible_to<T, std::string>) { return static_cast<std::string>(a) + static_cast<std::string>(b); } else { return std::to_string(a) + std::to_string(b); } } int main(){ int x{623}; int y{73}; auto result1 = concatenate(x,y); std::cout << result1 << std::endl; std::string s1 = "hello"; std::string s2 = "world"; auto result2 = concatenate(s1,s2); std::cout << result2 << std::endl; return 0; }
内容的提问来源于stack exchange,提问作者Gaston
相关产品推荐
相关产品推荐

