Hello,
Is there a way to locally rename members of a class? I'm looking for a way to have std::pair<t1,t2>::first be synonymous with std::pair<t1,t2>::type_specific. I'd prefer not to create my own type.
Thanks
Printable View
Hello,
Is there a way to locally rename members of a class? I'm looking for a way to have std::pair<t1,t2>::first be synonymous with std::pair<t1,t2>::type_specific. I'd prefer not to create my own type.
Thanks
{No}
<Bummer>
Will the constructor of this result in undefined behavior? (So far, so good)
Code:template<class T1, class T2>
struct point : public std::pair<T1,T2>
{
point() : std::pair<T1,T2>(), x(this->first), y(this->second) {}
T1 & x;
T2 & y;
};
(I don't see why it would.)
[Well,] (are we done with this?)
I thought that maybe the pair, and thus first and second wouldn't be constructed until the body of point's constructor. But it seems not. Actually, I think the C++ FAQ covers this...
It's safe. It's also a big waste of space, since your point class is suddenly two words larger. This will probably double or triple its size. No compiler will optimize these references away.
On the other hand, if you're not afraid of global functions, you can write them thus:
The syntax is admittedly a bit weird, but nothing out of the ordinary for hardcore generic programmers.Code:template <typename T1, typename T2>
T1 x(const std::pair<T1, T2> &pt)
{
return pt.first;
}
template <typename T1, typename T2>
T2 y(const std::pair<T1, T2> &pt)
{
return pt.second;
}
x(pt);
y(pt);
Or you could write accessor functions:
Code:template <typename T1, typename T2>
struct point : std::pair<T1, T2>
{
T1& x() { return this->first; }
T2& y() { return this->second; }
};
pt.x() = 100;
Hm. That's a good solution. Why wouldn't a clever optimizer remove the references in my code? Certainly it could notice that the references are used only exactly when that to which they refer could be used.
Compilers follow strict rules in the class layouts they generate. If there's a field "x" in the code, there'd better be something equivalent in the binary layout.
Optimizing these references away requires a data flow analyzer to prove that x and y ever only point to first and second of the same object, respectively. While this is very much within the realm of the possible for the compiler, this flow analyzer is only run when optimizations are turned on - it's very expensive to run. So it would depend on the optimization settings (and perhaps even more esoteric issues) whether the fields are there or not. However, the existence of the fields is a matter of the binary interface.
Breaking binary interface in codegen between release and debug builds is a big no-no.
Only codegen, though. Libraries far too often don't give a damn. The GCC guys are good with this - you can intermix debug and release code pretty freely, even with STL types in the mix. However, MS has no such scruples. The MS STL breaks binary interface with every little compiler switch, it sometimes seems.
Very interesting. Is there a reason why Microsoft does it this way?
No official one, no. My theory is that they're too lazy to do it properly.
After reading the Wikipedia article, I have this question:
What is a general reason for not wanting to change the binary interface between build profiles?
Suppose you have a number of projects. One of those is a library of basic utility classes. The second is a DLL used in several projects, which uses these utilities in its interface. The third is an executable.
If the binary interface changes between release and debug, then the executable, the DLL, and the basic utilities must always match in their build profile. Always.
OK, this isn't too much of a burden if the projects are all yours.
However, what if they aren't? Suppose the basic utility is the C++ standard library. Microsoft's SL changes binary interface not only between release and debug, but also between _SCL_SECURE=1 and 0. Suppose the DLL is not by you, but by a third party. You only get a release version, and you don't get the source. The DLL uses standard library components in its interface.
Then this means:
1) You cannot build debug variants of your program.
2) Your _SCL_SECURE setting must match that of the DLL. Oh, did I mention that this setting can slow down STL-intensive applications by a factor of 10?
I think it's because they're caught between a rock and a hard place.
They absolutely must have all that iterator checking stuff in there in debug buillds, which definitely involves extra fields, but they also must have the fastest possible release build implementation so that people will use their compiler for the nice fast code it generates.
So therefore you lose binary compatibility.
It's like that rule that you can have cheap, fast, or secure, but not all three.
They don't have a very fast release version by default - they erred on the side of safety, I think. But that's not the point.
The point is that they handled things in a very poor fashion. GCC's standard library is built so that in the rare cases where do mix up incompatible versions, you get linker errors. MS's version is built so that the program crashes. Oops, there goes the safety.
Also, in GCC's version the debug and the release version can and do coexist in a single runtime image (executable plus libraries). In MS's version this leads to load errors or crashes.