New user self-registration is disabled due to spam. For an account please email bugs-admin@lists.llvm.org with your e-mail address and full name.

Bug 15911 - User defined constructor lookup fails on local class defined inside template difinition and passed to another template as an template argument
Summary: User defined constructor lookup fails on local class defined inside template ...
Status: RESOLVED DUPLICATE of bug 9685
Alias: None
Product: clang
Classification: Unclassified
Component: C++11 (show other bugs)
Version: trunk
Hardware: PC Linux
: P normal
Assignee: Unassigned Clang Bugs
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-05-05 03:08 PDT by Ryou Ezoe
Modified: 2013-05-05 10:17 PDT (History)
3 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ryou Ezoe 2013-05-05 03:08:19 PDT
Clang fails to lookup user defined constructor of local class which is defined inside the template definition and passed to class template, or function template by explicit template argument specification.

For class template:

template < typename T >
struct S
{
    T t ;
    S() : t(0) { } } ;
} ;

// local class defined inside template definition.
template < typename T >
void f()
{
    struct local { local( int ) { } } ;

    S<local> s ;
}

// local class defined inside non-template definition.
void g()
{
    struct local { local( int ) { } } ;

    S<local> s ;
}


int main()
{
    f<void>() ; // error: no matching constructor for initialization of 'local'
    g() ; // OK, lookup works
}

Expected behavior: constructor lookup success.
Actual behavior: lookup fails.

For function template, only the explicit template argument specification cause this problem:

template < typename T >
void f( )
{
    T x(0) ;
}

template < typename T >
void call_f_template()
{
    struct local { local(int) {} } ;
    f<local>() ;
}

void call_f()
{
    struct local { local(int) {} } ;
    f<local>() ;
}


int main()
{
    call_f_template<void>() ; // error: no matching constructor for initialization of 'local' 
    call_f() ; // OK, lookup works.
}

Interestingly, argument deduction can workaround this problem.
In a context where argument deduction works, explicit template argument specification also works.

template < typename T >
void f( T const & )
{
    T x(0) ;
}

template < typename T >
void call_f_template()
{
    struct local { local(int) {} } ;
    local obj(0) ;
    f( obj ) ; // OK
    f<local>( obj ) ; // Also OK
}

int main()
{
    call_f_template<void>() ;
}


Only the lookup of user defined constructor fails.
Lookup of implicitly defined constructors works as expected.
Comment 1 Ryou Ezoe 2013-05-05 03:14:36 PDT
Sorry, there was a typo in the first post.

S() : t(0) { } } ;
should be
S() : t(0) { }
Comment 2 Richard Smith 2013-05-05 10:17:40 PDT

*** This bug has been marked as a duplicate of bug 9685 ***