Bug 34023 - Wrong using of user-defined conversion operator for converting rvalue to reference on constant.
Summary: Wrong using of user-defined conversion operator for converting rvalue to refe...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 3.4.5
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-11-08 01:53 UTC by Sergey Shandar
Modified: 2011-09-25 21:59 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work: 4.3.0
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Sergey Shandar 2007-11-08 01:53:48 UTC
// gcc version 3.4.5 (mingw-special)
class a
{
public:
	
	template<class T>
	operator T &() const
	{
		static int f;
		return f; // line # 10
	}

	/* 
	// unsafe workaround:
	operator a const &() const
	{
		return *this;
	}
	*/
};

int main()
{
	// : In member function `a::operator T&() const [with T = const a]':
	// :27:   instantiated from here
	// :10: error: invalid initialization of reference of type 'const a&' from expression of type 'int'
	a const &aa = a(); // line # 27
	/*
	// workaround:
	a const temp;
	a const &aa = temp;
	*/
}
Comment 1 Sergey Shandar 2007-11-08 01:58:13 UTC
I've checked other versions of compiler, such as 3.4.6 and 4.X.X. Can someone check?
Comment 2 Sergey Shandar 2007-11-08 02:03:55 UTC
(In reply to comment #1)
> I've checked other versions of compiler, such as 3.4.6 and 4.X.X. Can someone
> check?
> 
Sorry, I mean, I have *NOT*.
Comment 3 Sergey Shandar 2007-11-09 01:14:09 UTC
// Workaround:
class a
{
public:
        template<class T>
        operator T &() const
		throw(typename ::boost::disable_if<
			::boost::is_same<T, ref_t const> >::type *)
        {
                static int f;
                return f;
        }
};

int main()
{
        a const &aa = a(); // line # 27
        int &i = aa;
}


Comment 4 Andrew Pinski 2007-11-19 04:15:39 UTC
This works on the trunk.
Comment 5 Sergey Shandar 2007-11-29 00:04:00 UTC
(In reply to comment #3)
> // Workaround:
> class a
> {
> public:
>         template<class T>
>         operator T &() const
>                 throw(typename ::boost::disable_if<
>                         ::boost::is_same<T, ref_t const> >::type *)
>         {
>                 static int f;
>                 return f;
>         }
> };
> 
> int main()
> {
>         a const &aa = a(); // line # 27
>         int &i = aa;
> }
> 

This workaround should not work, according to the standard

14.8.2.2

    - All references in the function type of the function template to the corresponding template parameters are replaced by the specified template argument values. If a substitution in a template parameter or in the function type of the function template results in an invalid type, type deduction fails. [Note: The equivalent substitution in exception specifications is done only when the function is instantiated, at which point a program is ill-formed if the substitution results in an invalid type.] Type deduction may fail for the following reasons:

However, it works on GCC. It is another bug in GCC.
Comment 6 Paolo Carlini 2011-09-25 21:59:20 UTC
Fixed long ago.