metaprogramming exercise 2-0
I just finished the first exercise in the C++ meta programming book.
Then I checked what had been done before on this mailing list.
Here is my solution:
using namespace boost;
template
Chris Goller
His solution is SO much better then mine.
You can do even better (hint: you don't need to use add_const).
However, when I first saw it I thought it must be wrong because I assumed that add_const on a reference would would return a const reference. In other words, the code below would be false:
bool a = is_same
::type, int &>::value; However! bool "a" is true. So my question is why is "a" true? Why isn't add_const
::type == int const &?
It's not a very interesting answer: that's just the way the C++ type system works. The rule is, essentially, that add_const<T>::type is equivalent to T const. When you do that with int&, you get int& const Think of that as being like int* const The int isn't const, here; the pointer is. But unlike pointers, references can't be made to refer to new things. So int& const and int& are really the same type. Both are different from int const& where the int is immutable through that reference. HTH, -- Dave Abrahams Boost Consulting www.boost-consulting.com
David-
First, thanks for the response. BTW, I really like the book.
Okay, I understand what you are saying about add_const and how it works.
My next question is why was it implemented in that way? In other words,
was there a specific reason not to make a special case
for references such that add_const
Chris Goller
writes: His solution is SO much better then mine.
You can do even better (hint: you don't need to use add_const).
However, when I first saw it I thought it must be wrong because I assumed that add_const on a reference would would return a const reference. In other words, the code below would be false:
bool a = is_same
::type, int &>::value; However! bool "a" is true. So my question is why is "a" true? Why isn't add_const
::type == int const &? It's not a very interesting answer: that's just the way the C++ type system works.
The rule is, essentially, that
add_const<T>::type
is equivalent to
T const.
When you do that with int&, you get
int& const
Think of that as being like
int* const
The int isn't const, here; the pointer is. But unlike pointers, references can't be made to refer to new things. So
int& const
and
int&
are really the same type. Both are different from
int const&
where the int is immutable through that reference.
HTH,
Chris Goller wrote:
David-
First, thanks for the response. BTW, I really like the book.
Okay, I understand what you are saying about add_const and how it works.
My next question is why was it implemented in that way? In other words, was there a specific reason not to make a special case for references such that add_const
would be int const &?
FWIW, you will soon be able to get that effect without a metafunction. from http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#106 [example] int i; typedef int& RI; RI& r = i; // r has the type int& const RI& r = i; // r has the type const int& [/example] I'm not sure I like it, because a 'RI const' is 'int&', but a reference to a 'RI const' is 'int const&'. But maybe its useful that way. Cheers, Ian McCulloch
Ian McCulloch
Chris Goller wrote:
David-
First, thanks for the response. BTW, I really like the book.
Okay, I understand what you are saying about add_const and how it works.
My next question is why was it implemented in that way? In other words, was there a specific reason not to make a special case for references such that add_const
would be int const &? FWIW, you will soon be able to get that effect without a metafunction. from http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#106 [example] int i; typedef int& RI; RI& r = i; // r has the type int& const RI& r = i; // r has the type const int& [/example]
I'm not sure I like it, because a 'RI const' is 'int&', but a reference to a 'RI const' is 'int const&'. But maybe its useful that way.
Oh, that's very disturbing. What is the rationale for moving the
const inside the reference?
Ah, I see it in N1245:
template<class T> class X { f(const T&) ; /* ... */ };
X
FWIW, you will soon be able to get that effect without a metafunction. from http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#106 [example] int i; typedef int& RI; RI& r = i; // r has the type int& const RI& r = i; // r has the type const int& [/example]
I'm not sure I like it, because a 'RI const' is 'int&', but a reference to a 'RI const' is 'int const&'. But maybe its useful that way.
Oh, that's very disturbing. What is the rationale for moving the const inside the reference?
Ah, I see it in N1245:
template<class T> class X { f(const T&) ; /* ... */ };
X
x; // X ::f has the argument type const int& I'm not convinced that special rule is worth the breath and text needed to explain it. With any well-behaved class X, if f was written to work on a "const X&" argument, it will work equally well and correctly on a "X&" argument.
It's probably too late for objections now, though.
I don't think this affects add_const as such: Adding a const qualifier to a reference type still has no effect, it's only when you add a reference qualifier to a reference type that the cv-qualifiers get combined in this way. Assuming I've understood correctly of course! John.
Chris Goller
David-
First, thanks for the response. BTW, I really like the book.
Thank you; I'll make sure that Aleksey knows.
Okay, I understand what you are saying about add_const and how it works.
My next question is why was it implemented in that way? In other words, was there a specific reason not to make a special case for references such that add_const
would be int const &?
I can't speak for the designer (John Maddock, I think), but: 1. in general special cases are best avoided. They make interfaces harder to explain and use. 2. In this case there's no obvious advantage to making a special case. 3. The type traits library is basically designed to reflect the standard's definitions and rules. That would be a gratuitous deviation. -- Dave Abrahams Boost Consulting www.boost-consulting.com
However, when I first saw it I thought it must be wrong because I assumed that add_const on a reference would would return a const reference. In other words, the code below would be false:
bool a = is_same
::type, int &>::value; However! bool "a" is true. So my question is why is "a" true? Why isn't add_const
::type == int const &?
I thought the same thing at first but it makes senses when we compare
a reference to a constant pointer.
add_const
Thanks,
Chris
Philippe
participants (5)
-
Chris Goller
-
David Abrahams
-
Ian McCulloch
-
John Maddock
-
Philippe Mori