Bug 55908 - [4.8 Regression] Problem binding a const member function to a const object
Summary: [4.8 Regression] Problem binding a const member function to a const object
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.8.0
: P3 normal
Target Milestone: 4.8.0
Assignee: Jonathan Wakely
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-01-08 13:16 UTC by Philipp
Modified: 2013-01-08 21:03 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work: 4.7.3
Known to fail:
Last reconfirmed: 2013-01-08 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Philipp 2013-01-08 13:16:49 UTC
The following code fails to compile:

#include <functional>

typedef std::function<void (int) >func;

struct foo
{
        void f(int) const
        {
        }

        void g() const
        {
                func(std::bind(&foo::f, this, std::placeholders::_1));
        }
};

int main()
{
}

g++-4.8.0-alpha20130106 -std=c++11 test.cpp

test.cpp: In member function 'void foo::g() const':
test.cpp:14:55: error: no matching function for call to 'std::function<void(int)>::function(std::_Bind_helper<false, void (foo::*)(int)const, const foo* const, const std::_Placeholder<1>&>::type)'
   func(std::bind(&foo::f, this, std::placeholders::_1));
                                                       ^
test.cpp:14:55: note: candidates are:
In file included from test.cpp:1:0:
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.0-alpha20130106/include/g++-v4/functional:2252:2: note: template<class _Functor, class> std::function<_Res(_ArgTypes ...)>::function(_Functor)
  function(_Functor);
  ^
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.0-alpha20130106/include/g++-v4/functional:2252:2: note:   template argument deduction/substitution failed:
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.0-alpha20130106/include/g++-v4/functional:2227:7: note: std::function<_Res(_ArgTypes ...)>::function(std::function<_Res(_ArgTypes ...)>&&) [with _Res = void; _ArgTypes = {int}]
       function(function&& __x) : _Function_base()
       ^
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.0-alpha20130106/include/g++-v4/functional:2227:7: note:   no known conversion for argument 1 from 'std::_Bind_helper<false, void (foo::*)(int)const, const foo* const, const std::_Placeholder<1>&>::type {aka std::_Bind<std::_Mem_fn<void (foo::*)(int)const>(const foo*, std::_Placeholder<1>)>}' to 'std::function<void(int)>&&'
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.0-alpha20130106/include/g++-v4/functional:2430:5: note: std::function<_Res(_ArgTypes ...)>::function(const std::function<_Res(_ArgTypes ...)>&) [with _Res = void; _ArgTypes = {int}]
     function<_Res(_ArgTypes...)>::
     ^
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.0-alpha20130106/include/g++-v4/functional:2430:5: note:   no known conversion for argument 1 from 'std::_Bind_helper<false, void (foo::*)(int)const, const foo* const, const std::_Placeholder<1>&>::type {aka std::_Bind<std::_Mem_fn<void (foo::*)(int)const>(const foo*, std::_Placeholder<1>)>}' to 'const std::function<void(int)>&'
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.0-alpha20130106/include/g++-v4/functional:2207:7: note: std::function<_Res(_ArgTypes ...)>::function(std::nullptr_t) [with _Res = void; _ArgTypes = {int}; std::nullptr_t = std::nullptr_t]
       function(nullptr_t) noexcept
       ^
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.0-alpha20130106/include/g++-v4/functional:2207:7: note:   no known conversion for argument 1 from 'std::_Bind_helper<false, void (foo::*)(int)const, const foo* const, const std::_Placeholder<1>&>::type {aka std::_Bind<std::_Mem_fn<void (foo::*)(int)const>(const foo*, std::_Placeholder<1>)>}' to 'std::nullptr_t'
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.0-alpha20130106/include/g++-v4/functional:2200:7: note: std::function<_Res(_ArgTypes ...)>::function() [with _Res = void; _ArgTypes = {int}]
       function() noexcept
       ^
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.0-alpha20130106/include/g++-v4/functional:2200:7: note:   candidate expects 0 arguments, 1 provided


The problem goes away if the int parameter is taken out, or if g() is not const.
gcc-4.7.2 accepts the test case.
Comment 1 Jonathan Wakely 2013-01-08 13:33:56 UTC
Reduced:

#include <functional>

struct foo
{
        void f(int) const
        {
        }

        void g() const
        {
            auto mf = std::mem_fn(&foo::f);
            mf(this, 1);
        }
};
Comment 2 Jonathan Wakely 2013-01-08 13:35:18 UTC
Will fix it later today.
Comment 3 Jonathan Wakely 2013-01-08 21:01:23 UTC
Author: redi
Date: Tue Jan  8 21:01:14 2013
New Revision: 195035

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=195035
Log:
	PR libstdc++/55908
	* include/std/functional (_Mem_fn::operator()): Fix constraints to
	avoid ambiguity.
	* testsuite/20_util/function_objects/mem_fn/55908.cc: New.
	* testsuite/20_util/bind/ref_neg.cc: Adjust dg-error line numbers.

Added:
    trunk/libstdc++-v3/testsuite/20_util/function_objects/mem_fn/55908.cc
Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/include/std/functional
    trunk/libstdc++-v3/testsuite/20_util/bind/ref_neg.cc
Comment 4 Jonathan Wakely 2013-01-08 21:03:57 UTC
Fixed, thanks for the report.