|
Boost : |
From: Peter Dimov (pdimov_at_[hidden])
Date: 2000-11-02 09:13:47
From: "David Abrahams" <abrahams_at_[hidden]>
> Well, I think "not compiling" is outside the scope of the standard, at
least
> where the library is concerned. The standard never promises that invalid
> uses of the library will fail to compile.
Correct; but having as many invalid uses of the library as possible fail to
compile is a good thing, in general.
> I realize that. And I am not (neccessarily) against FTPS, though providing
> for it does seem like the more difficult way to solve the immediate needs
of
> users. It is clear that we need to explore the two approaches some more
> before we will come up with an acceptable solution.
I'll try to present a more systematic view on the matter. But first, an
example that is too good to skip:
#include <set>
struct base {};
namespace std { void swap(base &, base &); }
struct derived {};
void f()
{
derived d1, d2;
std::swap(d1, d2);
}
-- Suppose that I am a library implementor that wants to provide a specialized swap() for the (non-template) class X. The options are: namespace std { void swap(X &, X &); } // #1 template<> void std::swap(X &, X &); // #2 template<> void std::swap<X>(X &, X &); // #3 My analysis of the drawbacks of each method: #1: * allows invalid uses of std::swap to compile; * does not require the original std::swap declaration to be visible, which may lead to unexpected results. #2: * uses an error-prone specialization syntax, although in this particular case things can never go wrong. Nevertheless, programmers learn by example, so this style should not be encouraged. #3: * Syntax is hard to teach. Your choice? I, personally, would go with #3 any day. Now, consider the class template Y<T> case: namespace std { template<class T> void swap(Y<T> &, Y<T> &); // #4 } template<class T> void std::swap<Y<T> >(Y<T> &, Y<T> &); // #5 #4: * does not suffer from the #1 problems, but may interact badly with #3. #5: * requires core changes; * syntax is hard to teach, although not that hard for someone that already has mastered #3. Here it's either #4 or #5, the drawbacks balance each other. My personal preference is #5 because the feature is not without merits. An additional comment about the "hard to teach" argument. Which syntax is (a) easier to teach, (b) less dangerous and error-prone? template<> void f(int); or template<> void f<int>(int); -- Explanation of the example at the top: in implementation A including <set> makes std::swap visible, and std::swap(d1, d2) calls the original template. Implementation B does not make std::swap visible in this case, and std::swap(d1, d2) uses the overload. -- Peter Dimov Multi Media Ltd.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk