I've heard a little bit about reference-to-reference problem and this resolution. I'm not very good with C++ Committee terminology, but I understand the "Moved to DR" annotation in the link means that this is the current interpretation that standard-conforming compilers should adhere to.
I have this sample code that I can't understand:
template <typename T>
struct C {
void f(T&) { }
void f(const T&) { }
};
int main() {
C<int> x; // OK
C<int&> y; // compile error: f cannot be overloaded
C<const int&> z; // compile error: f cannot be overloaded
}
I understand the error in C<const int&>
case: using rules from DR #106 we get two methods with the same signature f(const int&). What I don't get is the C<int&>
case: shouldn't it generate exactly the same code as C<int>
(at least according to Stroustrup's resolution)?
To instantiate a template function explicitly, follow the template keyword by a declaration (not definition) for the function, with the function identifier followed by the template arguments. template float twice<float>(float original); Template arguments may be omitted when the compiler can infer them.
In order for any code to appear, a template must be instantiated: the template arguments must be provided so that the compiler can generate an actual class (or function, from a function template).
A function template starts with the keyword template followed by template parameter(s) inside <> which is followed by the function definition. In the above code, T is a template argument that accepts different data types ( int , float , etc.), and typename is a keyword.
Implicit instantiation means that the compiler automatically generates the concrete function or class for the provided template arguments. In general, the compiler also deduces the template arguments from the function's arguments. In C++17, the compiler can also deduce the template arguments for class templates.
DR only means "Defect Report", and to my knowledge, the described resolution hasn't made it (yet) to the standard. For this reason, I believe a strictly conforming C++03 implementation should not compile this code because of it is forming a reference to a reference.
[Edit] Just found a nice answer on this issue.
Interestingly, when I compile your code (Visual C++ 10 Express) I get errors, but also when I try this simpler case:
int main(int argc, char* argv[])
{
C<int> x; // OK
C<const int> x1; // error C2535: 'void C<T>::f(T &)' : member function
// already defined or declared
return 0;
}
Seems like the ref-to-ref collapsing defined in the DR you mentioned means that const
ref becomes a simple non-const ref within the template. My problem with this is that I don't understand why the second f
is not just ignored.
If I change C so that the second f is const
-qualified, this now compiles:
template <typename T>
struct C {
void f(T&) { }
void f(const T& t) const {}
};
The implication seems to be that when C
is instantiated with const
anything (ref or not), the two C::f
overloads are simply identical, and result in compile-time duplicate detection.
Perhaps somebody smarter than me can decipher the chain more definitively here.
EDIT: On reflection, it's not surprising here that T = const int&
results in the f
overloads being identically instantiated as
void f(const int&) {}
That's what the compiler is telling me:
#include "stdafx.h"
template <typename T>
struct C {
void f(T&) { }
void f(const T&) { }
};
int main() {
C<const int&> z; // compile error: f cannot be overloaded
return 0;
}
gives this error:
1>test.cpp(6): error C2535: 'void C<T>::f(T)' : member function already
defined or declared
1> with
1> [
1> T=const int &
1> ]
1> test.cpp(5) : see declaration of 'C<T>::f'
1> with
1> [
1> T=const int &
1> ]
1> test.cpp(10) : see reference to class template instantiation
'C<T>' being compiled
1> with
1> [
1> T=const int &
1> ]
I'm not even convinced this has anything to do with the DR.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With