This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: Bug in template parameter type deduction
>>>>> "Martin" == Martin v Loewis <martin@loewis.home.cs.tu-berlin.de> writes:
Martin> Thanks for your bug report. Can you please explain in more detail
Martin> why you think this is a bug in the compiler?
With pleasure. I apologize for being not precise enough.
Let's compare the following cases.
1 -------------------------------------------------------------------------
#include <iostream>
template <class Object>
class provided : public Object {
public:
const char* who() const { return "const"; }
const char* who() { return "non-const"; }
};
template <class Object> inline
provided<Object>&
provide(Object& x)
{
return reinterpret_cast<provided<Object>&>(x);
}
template <class Object> inline
const provided<Object>&
provide(const Object& x)
{
return reinterpret_cast<const provided<Object>&>(x);
}
class property { };
class object { public: object() { } };
int main()
{
object x1;
const object x2;
cout << "x1: " << provide(x1).who() << endl
<< "x2: " << provide(x2).who() << endl;
return 0;
}
It compiles fine and even prints correct results:
x1: non-const
x2: const
2 ----------------------------------------------------------------------------
#include <iostream>
template <class Object, class Property>
class provided : public Object {
public:
const char* who() const { return "const"; }
const char* who() { return "non-const"; }
};
template <class Property, class Object> inline
provided<Object,Property>&
provide(Object& x)
{
return reinterpret_cast<provided<Object,Property>&>(x);
}
template <class Property, class Object> inline
const provided<Object,Property>&
provide(const Object& x)
{
return reinterpret_cast<const provided<Object,Property>&>(x);
}
class property { };
class object { public: object() { } };
int main()
{
object x1;
const object x2;
cout << "x1: " << provide<property>(x1).who() << endl
<< "x2: " << provide<property>(x2).who() << endl;
return 0;
}
Doesn't compile:
prob12.cc: In function `int main()':
prob12.cc:33: call of overloaded `provide (const object &)' is ambiguous
prob12.cc:13: candidates are: class provided<const object,property> & provide<property, const object>(const object &)
prob12.cc:20: const class provided<object,property> & provide<property, object>(const object &
We have added the template parameter Property. Since it can't be deduced from the
function parameter list, we specify its type explicitly. Paragraph 14.8.1 #2
allows us to omit the trailing parameter Object, which still can be deduced, since
there is nothing about it that has changed against the case 1. Neither the
number of candidate functions nor the way of type deduction is different.
After all, why hasn't the possible instantiation
class provided<const object>& provide<const object>(const object &)
hindered the compiler in the case 1? It should have had good reasons to
consider it as a worse match that
const class provided<object>& provide<object>(const object &)
Probably because it's a more special match: const reference vs. reference in
the function parameter list. Why doesn't the same argumentation work in the
case 2?
With best regards,
Ewgenij Gawrilow
Dept. of Mathematics, Technical University of Berlin