为什么当错误无法访问时,该程序无法编译

Why does this program fail to compile when the error is unreachable?

本文关键字:程序 编译 访问 错误 为什么      更新时间:2023-10-16

我正在为可变位大小的像素颜色值创建一个类。无论如何,我让它工作,但有一些奇怪的东西:

#pragma pack(push, 1)
template <typename my_type>
struct c {
    my_type x;
    c() {}
    c(my_type x) { this->x = x; }
    template<typename target_type>
    c<target_type> convert() {
        if (std::is_same<my_type, target_type>::value) {
            return *this; //<- doesn't work
            return *reinterpret_cast<c<target_type>*>(this); //<- does work
        }
        int target_size = sizeof(((c<target_type>*)0)->x);
        int my_size = sizeof(x);
        if (my_size < target_size) {
            return c<target_type>(x << (target_size - my_size) * 8);
        }
        my_type rounder = ((x >> (my_size - target_size) * 8 - 1) & 9) > 4;
        return c<target_type>((x >> (my_size - target_size) * 8) + rounder);    
    }
};
#pragma pack(pop)

在我标记的行上,我应该能够只返回*this,但是如果我这样做并尝试使用以下测试进行编译:

c<uint8_t> a;
c<uint32_t> b(2147483647);
a = b.convert<uint8_t>();

然后我得到错误

cannot convert from c<uint32_t> to c<uint8_t>

这是没有意义的,因为如果它是相同的类型,它不应该转换任何东西,而uint32_t不是这种情况uint8_t

这是在MSVC上,有谁知道为什么会这样?

在您的情况下,当您这样做时:

if (std::is_same<my_type, target_type>::value) {
    return *this;
}

my_typeuint32_ttarget_typeuint8_t。因此,std::is_same<my_type, target_type>::value false,因此不会执行return *this;

但是,它将被编译!并且编译器报告错误,因为您绝对无法在应该返回c<uint8_t>的函数中返回*this(类型 c<uint32_t>(,因为它们是不同的类型......

模板函数的每个路径都必须对编译有效,即使其中一些路径受到运行时执行保护......

在这种情况下,您需要的是函数的两个版本,一个用于同一类型,另一个用于其他类型。一种可能性:

template<typename target_type>
typename std::enable_if<std::is_same<my_type, target_type>::value, c<target_type> >::type
convert() {
    return *this;
}
template<typename target_type>
typename std::enable_if<!std::is_same<my_type, target_type>::value, c<target_type> >::type
convert() {
    int target_size = sizeof(((c<target_type>*)0)->x);
    int my_size = sizeof(x);
    if (my_size < target_size) {
        return c<target_type>(x << (target_size - my_size) * 8);
    }
    my_type rounder = ((x >> (my_size - target_size) * 8 - 1) & 9) > 4;
    return c<target_type>((x >> (my_size - target_size) * 8) + rounder);    
}

其工作原理是,std::enable_if在类型相同的情况下启用第一个函数,在类型不同时启用所有其他函数