g++ 8.1 template deduction ambiguity with std flag equal to 'c++17'
Clash Royale CLAN TAG#URR8PPP
up vote
25
down vote
favorite
I have code which is differently interpreted by g++ with the c++14
and c++17
standard flags:
#include <iostream>
#include <vector>
template<class T, class A>
void func(const std::vector<T, A>&v)
std::cout << 1 << std::endl;
template<typename T, template <typename>class Vector>
void func(const Vector<T>&v)
std::cout << 2 << std::endl;
void f()
std::vector<int> v;
func(v);
int main()
f();
return 0;
When I'm trying compile this code with command
g++ -std=c++14 -Wall -pedantic main.cpp
everything works just fine.
But when I'm trying to compile this code with command
g++ -std=c++17 -Wall -pedantic main.cpp
I get this error:
main.cpp: In function 'void f()':
main.cpp:19:11: error: call of overloaded 'func(std::vector<int>&)' is ambiguous
func(v);
^
main.cpp:5:6: note: candidate: 'void func(const std::vector<_Tp, _Alloc>&) [with T = int; A = std::allocator<int>]'
void func(const std::vector<T, A>&v)
^~~~
main.cpp:11:6: note: candidate: 'void func(const Vector<T>&) [with T = int; Vector = std::vector]'
void func(const Vector<T>&v)
I can't figure out what is wrong with this code from the C++17 standard's point of view.
c++ templates g++ c++14 c++17
add a comment |Â
up vote
25
down vote
favorite
I have code which is differently interpreted by g++ with the c++14
and c++17
standard flags:
#include <iostream>
#include <vector>
template<class T, class A>
void func(const std::vector<T, A>&v)
std::cout << 1 << std::endl;
template<typename T, template <typename>class Vector>
void func(const Vector<T>&v)
std::cout << 2 << std::endl;
void f()
std::vector<int> v;
func(v);
int main()
f();
return 0;
When I'm trying compile this code with command
g++ -std=c++14 -Wall -pedantic main.cpp
everything works just fine.
But when I'm trying to compile this code with command
g++ -std=c++17 -Wall -pedantic main.cpp
I get this error:
main.cpp: In function 'void f()':
main.cpp:19:11: error: call of overloaded 'func(std::vector<int>&)' is ambiguous
func(v);
^
main.cpp:5:6: note: candidate: 'void func(const std::vector<_Tp, _Alloc>&) [with T = int; A = std::allocator<int>]'
void func(const std::vector<T, A>&v)
^~~~
main.cpp:11:6: note: candidate: 'void func(const Vector<T>&) [with T = int; Vector = std::vector]'
void func(const Vector<T>&v)
I can't figure out what is wrong with this code from the C++17 standard's point of view.
c++ templates g++ c++14 c++17
add a comment |Â
up vote
25
down vote
favorite
up vote
25
down vote
favorite
I have code which is differently interpreted by g++ with the c++14
and c++17
standard flags:
#include <iostream>
#include <vector>
template<class T, class A>
void func(const std::vector<T, A>&v)
std::cout << 1 << std::endl;
template<typename T, template <typename>class Vector>
void func(const Vector<T>&v)
std::cout << 2 << std::endl;
void f()
std::vector<int> v;
func(v);
int main()
f();
return 0;
When I'm trying compile this code with command
g++ -std=c++14 -Wall -pedantic main.cpp
everything works just fine.
But when I'm trying to compile this code with command
g++ -std=c++17 -Wall -pedantic main.cpp
I get this error:
main.cpp: In function 'void f()':
main.cpp:19:11: error: call of overloaded 'func(std::vector<int>&)' is ambiguous
func(v);
^
main.cpp:5:6: note: candidate: 'void func(const std::vector<_Tp, _Alloc>&) [with T = int; A = std::allocator<int>]'
void func(const std::vector<T, A>&v)
^~~~
main.cpp:11:6: note: candidate: 'void func(const Vector<T>&) [with T = int; Vector = std::vector]'
void func(const Vector<T>&v)
I can't figure out what is wrong with this code from the C++17 standard's point of view.
c++ templates g++ c++14 c++17
I have code which is differently interpreted by g++ with the c++14
and c++17
standard flags:
#include <iostream>
#include <vector>
template<class T, class A>
void func(const std::vector<T, A>&v)
std::cout << 1 << std::endl;
template<typename T, template <typename>class Vector>
void func(const Vector<T>&v)
std::cout << 2 << std::endl;
void f()
std::vector<int> v;
func(v);
int main()
f();
return 0;
When I'm trying compile this code with command
g++ -std=c++14 -Wall -pedantic main.cpp
everything works just fine.
But when I'm trying to compile this code with command
g++ -std=c++17 -Wall -pedantic main.cpp
I get this error:
main.cpp: In function 'void f()':
main.cpp:19:11: error: call of overloaded 'func(std::vector<int>&)' is ambiguous
func(v);
^
main.cpp:5:6: note: candidate: 'void func(const std::vector<_Tp, _Alloc>&) [with T = int; A = std::allocator<int>]'
void func(const std::vector<T, A>&v)
^~~~
main.cpp:11:6: note: candidate: 'void func(const Vector<T>&) [with T = int; Vector = std::vector]'
void func(const Vector<T>&v)
I can't figure out what is wrong with this code from the C++17 standard's point of view.
c++ templates g++ c++14 c++17
c++ templates g++ c++14 c++17
edited Aug 17 at 16:36
Peter Mortensen
13k1983111
13k1983111
asked Aug 17 at 10:13
Yuri Dolotkazin
30028
30028
add a comment |Â
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
30
down vote
accepted
The behavior changed since C++17.
Before C++17, the code works because std::vector
has two template parameters (the 2nd one has the default argument std::allocator<T>
), while the template template parameter Vector
is declared to have only one, they don't match then the 2nd func
won't be considered.
Since C++17 (CWG 150), the default template arguments are allowed for a template template argument to match a template template parameter with fewer template parameters. That means both func
become valid candidates and then leads to ambiguity.
template<class T> class A /* ... */ ;
template<class T, class U = T> class B /* ... */ ;
template<template<class> class P> class X /* ... */ ;
X<A> xa; // OK
X<B> xb; // OK in C++17 after CWG 150
// Error earlier: not an exact match
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
30
down vote
accepted
The behavior changed since C++17.
Before C++17, the code works because std::vector
has two template parameters (the 2nd one has the default argument std::allocator<T>
), while the template template parameter Vector
is declared to have only one, they don't match then the 2nd func
won't be considered.
Since C++17 (CWG 150), the default template arguments are allowed for a template template argument to match a template template parameter with fewer template parameters. That means both func
become valid candidates and then leads to ambiguity.
template<class T> class A /* ... */ ;
template<class T, class U = T> class B /* ... */ ;
template<template<class> class P> class X /* ... */ ;
X<A> xa; // OK
X<B> xb; // OK in C++17 after CWG 150
// Error earlier: not an exact match
add a comment |Â
up vote
30
down vote
accepted
The behavior changed since C++17.
Before C++17, the code works because std::vector
has two template parameters (the 2nd one has the default argument std::allocator<T>
), while the template template parameter Vector
is declared to have only one, they don't match then the 2nd func
won't be considered.
Since C++17 (CWG 150), the default template arguments are allowed for a template template argument to match a template template parameter with fewer template parameters. That means both func
become valid candidates and then leads to ambiguity.
template<class T> class A /* ... */ ;
template<class T, class U = T> class B /* ... */ ;
template<template<class> class P> class X /* ... */ ;
X<A> xa; // OK
X<B> xb; // OK in C++17 after CWG 150
// Error earlier: not an exact match
add a comment |Â
up vote
30
down vote
accepted
up vote
30
down vote
accepted
The behavior changed since C++17.
Before C++17, the code works because std::vector
has two template parameters (the 2nd one has the default argument std::allocator<T>
), while the template template parameter Vector
is declared to have only one, they don't match then the 2nd func
won't be considered.
Since C++17 (CWG 150), the default template arguments are allowed for a template template argument to match a template template parameter with fewer template parameters. That means both func
become valid candidates and then leads to ambiguity.
template<class T> class A /* ... */ ;
template<class T, class U = T> class B /* ... */ ;
template<template<class> class P> class X /* ... */ ;
X<A> xa; // OK
X<B> xb; // OK in C++17 after CWG 150
// Error earlier: not an exact match
The behavior changed since C++17.
Before C++17, the code works because std::vector
has two template parameters (the 2nd one has the default argument std::allocator<T>
), while the template template parameter Vector
is declared to have only one, they don't match then the 2nd func
won't be considered.
Since C++17 (CWG 150), the default template arguments are allowed for a template template argument to match a template template parameter with fewer template parameters. That means both func
become valid candidates and then leads to ambiguity.
template<class T> class A /* ... */ ;
template<class T, class U = T> class B /* ... */ ;
template<template<class> class P> class X /* ... */ ;
X<A> xa; // OK
X<B> xb; // OK in C++17 after CWG 150
// Error earlier: not an exact match
edited Aug 17 at 10:38
answered Aug 17 at 10:19
songyuanyao
85k9163222
85k9163222
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f51893159%2fg-8-1-template-deduction-ambiguity-with-std-flag-equal-to-c17%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password