gpt4 book ai didi

c++ - 是否有可能避免最终不会运行的c++模板函数部分出现错误?

转载 作者:行者123 更新时间:2023-11-30 01:34:37 25 4
gpt4 key购买 nike

我有一个模板,其中有两个整数作为输入。一个可能比另一个更大。我的代码相应地进行了转换,因此结果符合目标类型

这里是这个函数的基本概念:

template<typename S, typename D>
D convert(S a)
{
return static_cast<D>(a);
}

不过,当 SD 之间的大小发生变化时,我想移动该值。所以我添加了几个条件:

    if(sizeof(S) < sizeof(D))
{
return a << (sizeof(D) - sizeof(S)) * 8;
}

if(sizeof(S) > sizeof(D))
{
return a >> (sizeof(S) - sizeof(D)) * 8;
}

问题是我得到了这些错误:

conversions.cpp: In instantiation of ‘void convert(buffer_&) [with S = unsigned char; D = short unsigned int; buffer_t = std::vector]’:
conversions.cpp: required from here
conversions.cpp: error: right shift count >= width of type [-Werror=shift-count-overflow]

  d[idx] = convert_sign<S, D>(static_cast<std::int64_t>(s[idx]) >> (sizeof(S) - sizeof(D)) * 8);

_注意:对于那些不理解的人,(sizeof(S) - sizeof(D))(sizeof(D) - sizeof(S)) 当在错误 if() block 将是,因此被视为非常大的移位参数(因为移位参数被视为无符号值,它非常大而且不是负数,无论如何 sizeof() 返回一个未签名的 std::size_t。)

显然,我可以使用 pragma 来忽略警告并完成它。

不过,我所期望的是,具有 falseif() 将不会被编译,因此不会出现错误,因为这是在编译时发生的(即编译器在编译时知道 if() block 是否会被执行。)有没有办法不使用 pragma 并仍然避免错误?

最佳答案

What I was expecting, though, was that the if() that has false would just not get compiled so there would no errors since that happens at compile time (i.e. the compiler knows whether the if() block will be executed or not at the time it gets compiled.)

您描述的是 if constexpr 的行为不幸的是,它只能从 C++17 开始使用

当你写作时

if constexpr ( some_compile_time_test )
some_code_1;
else
some_code_2;

哪里some_compile_time_test是一个可以决定编译时的测试(如sizeof(S) < sizeof(D)),编译器编译some_code_1 -- 并完全忽略 some_code_2 -- 当测试是 true反之亦然,否则

如果你只写

if ( some_test )
some_code_1;
else
some_code_2;

如果测试 some_test 并不重要编译时是否可推导:编译器可以优化代码,忽略未使用的部分,但该部分必须是可编译的。

Pre C++17(主要但不仅是 C++11 和 C++14)你必须开发两个(或更多)不同的函数/方法。

查找“SFINAE”和“标签调度”以查看一些有用的方法。

SFINAE 的一个例子

template <typename S, typename D>
typename std::enable_if<(sizeof(S)<sizeof(D)), S>::type convert (S a)
{ return a << (sizeof(D) - sizeof(S)) * 8; }

template <typename S, typename D>
typename std::enable_if<(sizeof(S)>sizeof(D)), S>::type convert (S a)
{ return a >> (sizeof(S) - sizeof(D)) * 8; }

和一个标签分发的例子(两者注意:代码未经测试)

template <typename S, typename D>
S convert (S a, std::true_type)
{ return a << (sizeof(D) - sizeof(S)) * 8; }

template <typename S, typename D>
S convert (S a, std::false_type)
{ return a >> (sizeof(S) - sizeof(D)) * 8; }

template <typename S, typename D>
S convert (S a)
{ return convert<S, D>(a, std::integral_constant<bool, (sizeof(S)<sizeof(D))>{}); }

关于c++ - 是否有可能避免最终不会运行的c++模板函数部分出现错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56029417/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com