考虑以下类型:

template<typename T> struct View
{
    T*     data;
    size_t size;
};

View<T>&从到转换是否有效View<const T>&

它会引发未定义的行为吗?

我怀疑该转换在所有编译器上都将按预期工作,但由于严格的别名规则,根据标准,其在技术上将是未定义的行为

8

  • 1
    C++ 中的严格别名规则规定,除了少数例外,一种类型的对象不能通过指向不同类型的指针来访问。但是,此规则对 const 和 volatile 限定类型有特定限制。


    – 

  • 1
    这是未定义的行为。但您可以实现转换构造函数或转换运算符,以允许从 转换View<T>View<const T>


    – 

  • 4
    @Dmitrii 将 a 转换foo<T>&foo<const T>&并不免于严格的别名规则,它们是不相关的类型。您可以data单独转换为 ,const T*但这与将引用转换为整个结构不同。


    – 

  • 1
    我们注意到shared_ptr,其强制类型转换的是其内部指针而不是外部指针。


    – 

  • 2
    这是形式上未定义的行为,但我在许多 C++ 程序中都看到过这种确切的诡计,而且它“似乎在每个编译器和体系结构上都有效”。如果这是一个语言律师问题(即您只关心它是否被正式定义),那么答案就很简单了。但是,如果您正在寻找一个失败的反例,那么这是一个更难的问题。您应该明确您关心的是这两者中的哪一个,否则这个问题很可能只会引发大量无意义的争论。


    – 


最佳答案
1

View<T>View<const T>不相关的类型,因此将引用从第一个类型转换为第二个类型违反了严格的别名规则并导致UB(未定义行为)。

确实,将 转换T*为是有效的const T*(因为这些是相关类型),但是在将引用转换为包含此类成员的类时,这并不相关(View)。

它可能在您的编译器上按您的预期工作,但按照标准它仍然是未定义的行为,因此我不建议依赖它。

正如@FrançoisAndrieux一样,您可以通过添加转换构造函数或转换运算符来处理它,以允许从 转换View<T>View<const T>