This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/51817] New: [C++11] argument deduction fails when A-type parameter-type-list has additional parameters
- From: "hstong at ca dot ibm.com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Tue, 10 Jan 2012 23:55:30 +0000
- Subject: [Bug c++/51817] New: [C++11] argument deduction fails when A-type parameter-type-list has additional parameters
- Auto-submitted: auto-generated
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51817
Bug #: 51817
Summary: [C++11] argument deduction fails when A-type
parameter-type-list has additional parameters
Classification: Unclassified
Product: gcc
Version: 4.6.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
AssignedTo: unassigned@gcc.gnu.org
ReportedBy: hstong@ca.ibm.com
Host: powerpc64-unknown-linux-gnu
Target: powerpc64-unknown-linux-gnu
The behaviour of the following test case was clarified in paper N2242 for
variadic templates.
In the 2011 FDIS subclause 14.8.2.5 [temp.deduct.type] paragraph 10,
deduction from a function type considers P/A pairs from the
parameter-type-list only where the "P" function type has a parameter.
Deduction is not specified to fail if there are additional parameters in the
corresponding "A" function type.
I use the --std=c++0x option; however, I do not believe that the C++03 wording
prohibits the C++2011 behaviour.
The second call to foo in main should be the same as the first (working) call.
If compiled and linked with -DVERBOSE, the resulting program should print:
Converting from A<void (int, char)> to A<void (int)>.
foo(A<void (int)> called.
Converting from A<void (int, char)> to A<void (int)>.
foo(A<void (int)> called.
### Self-contained source:
$ cat parmlistlen.cpp
template <typename U>
struct A {
template <typename V> operator A<V>();
};
template <typename T> void foo(A<void (T)>);
void foo();
int main() {
A<void (int, char)> a;
foo<int>(a);
foo(a); // seems to fail in argument deduction
}
#ifdef VERBOSE
extern "C" int printf(const char *, ...);
template <typename T> struct tyStr { static const char str[]; };
template <> const char tyStr<void (int, char)>::str[] = "void (int, char)";
template <> const char tyStr<void (int)>::str[] = "void (int)";
template <typename T>
void foo(A<void (T)>) {
printf("foo(A<%s> called.\n", tyStr<void (T)>::str);
}
template <typename U>
template <typename V>
A<U>::operator A<V>() {
printf("Converting from A<%s> to A<%s>.\n", tyStr<U>::str, tyStr<V>::str);
return A<V>();
}
#endif
### Compiler Invocation:
$ g++-4.6.0 --std='c++0x' parmlistlen.cpp
parmlistlen.cpp: In function 'int main()':
parmlistlen.cpp:12:9: error: no matching function for call to 'foo(A<void(int,
char)>&)'
parmlistlen.cpp:12:9: note: candidates are:
parmlistlen.cpp:6:28: note: template<class T> void foo(A<void(T)>)
parmlistlen.cpp:7:6: note: void foo()
parmlistlen.cpp:7:6: note: candidate expects 0 arguments, 1 provided
### g++ -v output:
$ g++-4.6.0 -v
Using built-in specs.
COLLECT_GCC=g++-4.6.0
COLLECT_LTO_WRAPPER=/data/gcc/libexec/gcc/powerpc64-unknown-linux-gnu/4.6.0/lto-wrapper
Target: powerpc64-unknown-linux-gnu
Configured with: ./configure --prefix=/data/gcc --program-suffix=-4.6.0
--disable-libssp --disable-libgcj --enable-version-specific-runtime-libs
--with-cpu=default32 --enable-secureplt --with-long-double-128 --enable-shared
--enable-__cxa_atexit --enable-threads=posix --enable-languages=c,c++,fortran
--with-gmp=/usr/local
Thread model: posix
gcc version 4.6.0 (GCC)