c++模板约束

文章讲述了C++中模板编程的错误信息通常难以理解,通过引入`requires`子句和`concept`来约束模板参数类型,可以显著改善编译时的错误提示,提高代码可读性和调试效率。
摘要由CSDN通过智能技术生成

模板编程的错误信息非常难读,例如下面例子

#include <iostream>

template <typename T>
    T multiply(T first, T second)
{
        return first * second;
}

int main()
{
    std::cout << multiply(3, 5) << std::endl;
    std::cout << multiply("1", "2") << std::endl;
}

在倒数第二行,我们传入了错误的参数,他的报错是这样的

1>E:\codes\TestCpp\TestCpp\main.cpp(6,22): error C2296: '*': not valid as left operand has type 'T'
1>E:\codes\TestCpp\TestCpp\main.cpp(6,22): error C2296:         with
1>E:\codes\TestCpp\TestCpp\main.cpp(6,22): error C2296:         [
1>E:\codes\TestCpp\TestCpp\main.cpp(6,22): error C2296:             T=const char *
1>E:\codes\TestCpp\TestCpp\main.cpp(6,22): error C2296:         ]
1>E:\codes\TestCpp\TestCpp\main.cpp(6,22):
1>the template instantiation context (the oldest one first) is
1>	E:\codes\TestCpp\TestCpp\main.cpp(12,18):
1>	see reference to function template instantiation 'T *multiply<const char*>(T,T)' being compiled
1>        with
1>        [
1>            T=const char *
1>        ]
1>E:\codes\TestCpp\TestCpp\main.cpp(6,22): error C2297: '*': not valid as right operand has type 'T'
1>E:\codes\TestCpp\TestCpp\main.cpp(6,22): error C2297:         with
1>E:\codes\TestCpp\TestCpp\main.cpp(6,22): error C2297:         [
1>E:\codes\TestCpp\TestCpp\main.cpp(6,22): error C2297:             T=const char *
1>E:\codes\TestCpp\TestCpp\main.cpp(6,22): error C2297:         ]
1>Done building project "TestCpp.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

如果我们使用requires子句约束模板,错误信息可读性就会高很多,我们上面的程序改成这样:

#include <iostream>

template <typename T>
requires std::integral<T> || std::floating_point<T>
    T multiply(T first, T second)
{
        return first * second;
}

int main()
{
    std::cout << multiply(3, 5) << std::endl;
    std::cout << multiply("1", "2") << std::endl;
}

这个时候不需要编译,ide已经提示我们输入了错了的参数,如果我们编译一下

1>E:\codes\TestCpp\TestCpp\main.cpp(13,18): error C2672: 'multiply': no matching overloaded function found
1>E:\codes\TestCpp\TestCpp\main.cpp(5,7):
1>could be 'T multiply(T,T)'
1>	E:\codes\TestCpp\TestCpp\main.cpp(13,18):
1>	the associated constraints are not satisfied
1>		E:\codes\TestCpp\TestCpp\main.cpp(4,10):
1>		the concept 'std::integral<const char*>' evaluated to false
1>			C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\concepts(70,20):
1>			the constraint was not satisfied
1>		E:\codes\TestCpp\TestCpp\main.cpp(4,30):
1>		the concept 'std::floating_point<const char*>' evaluated to false
1>			C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\concepts(79,26):
1>			the constraint was not satisfied
1>Done building project "TestCpp.vcxproj" -- FAILED.

错误信息简单了很多

如果我们对模板的约束很多,岂不是会有一个超级长的声明?
这个问题可以用concept解决!

template<typename T>
concept Numeric = std::integral<T> || std::floating_point<T>;

template <typename T>
requires Numeric<T>
    T multiply(T first, T second)
{
        return first * second;
}

更简单一点,直接写成

template<typename T>
concept Numeric = std::integral<T> || std::floating_point<T>;

template <Numeric T>
    T multiply(T first, T second)
{
        return first * second;
}

更简单一点,auto大法好!

template<typename T>
concept Numeric = std::integral<T> || std::floating_point<T>;

auto multiply(Numeric auto first, Numeric auto second)
{
        return first * second;
}
  • 10
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值