我可以安全地假设std::pair
的第一个元素的地址可以用作两个元素数组的地址吗?当然,这对中的两个元素都是相同的类型。以下代码适用于g ++ 7.2,clang 3.8和vc ++ 14
void foo(int* a)
{
std::cout << std::to_string(a[0]) << ", " << std::to_string(a[1]) << std::endl;
}
int main()
{
std::pair<int, int> bar(42, 24);
foo(&bar.first);
return 0;
}
由于std::pair
是一个相当简单的类,我确信这个案例可以概括,但我不确定到什么程度。例如,它是模板类对问题有什么影响吗?
如果我不能安全地做到这一点,为什么?如果它被认为是有效的代码,那么这有什么保证呢?
答案 0 :(得分:4)
将我的评论写成答案:
除了数组(如MSalters所指出的),绝对不允许读取超出对象边界的内容。虽然单个变量可以被认为是长度为1的数组(因此a[0]
因其定义为*(a+0)
而被允许),所以读取其不存在的第二个元素&#34; via a[1]
是未定义的行为,因为它超出了bar.first
的边界。这两个对象可能是较大聚合对象(其实现未知)的一部分,但不会改变它。
请注意,像这样的许多边界违规都可以使用已知的体系结构,编译器,库和编译器选项;这个特定的应该在任何地方都可以使用,因为int
被设计为在给定的机器上具有自然的单词大小,因此可以在结构中没有填充的情况下对齐,std::pair
当然是;但是没有保证,包括恶意编译器。实际上,呈现的程序(即作为一个翻译单元)可以静态地证明是不正确的。编译器可以检测到并拒绝编译。
答案 1 :(得分:2)
cpp引用没有说明如何定义模板化的struct std :: pair(http://en.cppreference.com/w/cpp/utility/pair)。 不能保证第一个和第二个参数将被打包在一起。即使大多数实现可能看起来像
template<class A, class B>
struct pair {
[...]
A first;
B second;
[...]
}
对于int,您的代码可能有效。对于其他类型,假设std :: pair的内部结构看起来是非常不安全的。
如果需要元素的整数数组,则必须将它们复制到一个单独的位置。