我已成功地編譯和運行C++代碼即使它不應該。成員仍然是公開可見
下面的代碼片段不被編譯:
template<typename T, size_t SIZE>
struct Vector {
Vector(std::initializer_list<T> data) {
std::copy(data.begin(), data.end(), this->data);
}
Vector(T(&data)[SIZE]) {
std::copy(data, data + SIZE, this->data);
}
protected:
#pragma pack(push, 1) //stores the alignment of aggregate types and sets it to 1 byte
union {
struct {
T x, y, z, w;
};
T data[SIZE];
};
#pragma pack(pop) //restore old data alignment
};
template<typename T>
struct Vector2 : public Vector<T, 2> {
using Vector<T, 2>::Vector<T, 2>;
Vector2(T x = 0, T y = 0) :
Vector({ x, y }){}
Vector2(const Vector& vec) :
Vector(vec) {}
using Vector::x;
using Vector::y;
};
int main() {
double floats[2]{ 2, 3 };
Vector2<double> v{ floats };
Vector<double, 2> c{ 5., 6. };
std::cout << "v.x = " << v.x;
//Is oke, v.x is visible here because of the public using statement
std::cout << " c.x = " << c.x << "\n";
//Is not oke, c is not a Vector2<double>. It is a Vector<double, 2> so its member x is protected and thus not visible from here.
}
輸出:v.x = 2 c.x = 5
所以這個方案不僅成功地編譯和鏈接,但它也運行並打印敏感數據。 我嘗試將c
更改爲Vector<double, 3>
,但這並沒有改變任何內容。此外,成員z
和w
也可以看到,就像x
和y
一樣。但是,data
不可見(例如,std::cout << c.data[0];
不會按預期進行編譯)。
智能感知比在這種情況下,聰明的編譯器,因爲它成功地檢測到錯誤,並抱怨它。
我使用的Visual Studio 2013。
PS:
方問題:我找到的編譯器的另一個怪癖在這相同的代碼段。如果我更改以下行:
using Vector<T, 2>::Vector<T, 2>;
到:
using Vector<T, 2>::Vector;
我得到這個編譯器錯誤:error C2886: 'Vector<T,0x02>' : symbol cannot be used in a member using-declaration
如果我將其更改爲:
using Vector::Vector;
編譯器崩潰全部與:fatal error C1001: An internal error has occurred in the compiler. see reference to class template instantiation 'Vector2<T>' being compiled
。
這(它例如崩潰的事實)可能只是在編譯器中的錯誤,但是,如果有人知道,我還是想知道爲什麼既不是該行編譯兩個替代形式。