C++.Coding.Standards.1918.Rules.Guidelines [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

C++.Coding.Standards.1918.Rules.Guidelines [Electronic resources] - نسخه متنی

Herb Sutter, Andrei Alexandrescu

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید


Discussion


By following this advice, you will avoid having to track down hard-to-diagnose errors in your code and avoid having to know about excessively subtle language details that you, well, should never have to know about.

Consider this actual example that was posted publicly to a newsgroup:

#include <vector>
namespace N {
struct X {};
template<typename T>
int* operator+( T , unsigned ) {

/* do something */ }
}
int main() {
std::vector<N::X> v(5);
v[0] ;
}

The statement

v[0]; compiles on some standard library implementations but not on others. To make a very long story moderately less long (take a deep breath): The exceedingly subtle problem is that inside most implementations of

vector<T>::operator[] lurks code like

v.begin() + n , and the name lookup for that

operator+ function

might reach out into the namespace (here

N ) of the type that

vector is instantiated with (here

X ). Whether it reaches out into

N like that depends on how

vector<T>::iterator happens to be defined in that release of that standard library implementationbut if it does look into

N , then it will find

N::operator+ . Finally, depending on the types involved, the compiler might just discover that

N::operator+ is a better match than the

std::operator+ for

vector<T>::iterator s that was provided (and intended to be called) in that standard library implementation. (One way that the standard library implementation could protect itself from this is to not write code like

v.begin() + n in that way, which injects an unintentional point of customization: Either arrange for

v.begin() 's type to not depend in any way on the template parameter, or rewrite the call to

operator+ as a qualified call. See Item 65)

In short, you'll almost certainly never figure out what's going on from the error messageif you're lucky enough to get an error message, that is, because you might happen to hit the worst of all possible worlds where

N::operator+ is chosen but unfortunately turns out to be compilable, although completely unintended and wildly wrong.

If you think you haven't been bit by this, just think back: Can you remember a time when you wrote code that used the standard library (for example) and got mysterious and incomprehensible compiler errors? And you kept slightly rearranging your code and recompiling, and rearranging some more and compiling some more, until the mysterious compile errors went away, and then you happily continued onwith at best a faint nagging curiosity about why the compiler didn't like the only-ever-so-slightly different arrangement of the code you wrote at first? We've all had those days, and the odds are decent that the mystery culprit was some form of the aforementioned problem, where ADL pulled in names from other namespaces inappropriately just because types from those namespaces were being used nearby.Item 57.


/ 521