g++ 8.1 template deduction ambiguity with std flag equal to 'c++17'

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
25
down vote

favorite
3












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.










share|improve this question



























    up vote
    25
    down vote

    favorite
    3












    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.










    share|improve this question

























      up vote
      25
      down vote

      favorite
      3









      up vote
      25
      down vote

      favorite
      3






      3





      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.










      share|improve this question















      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






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Aug 17 at 16:36









      Peter Mortensen

      13k1983111




      13k1983111










      asked Aug 17 at 10:13









      Yuri Dolotkazin

      30028




      30028






















          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






          share|improve this answer






















            Your Answer





            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "1"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            convertImagesToLinks: true,
            noModals: false,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













             

            draft saved


            draft discarded


















            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






























            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






            share|improve this answer


























              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






              share|improve this answer
























                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






                share|improve this answer














                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







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Aug 17 at 10:38

























                answered Aug 17 at 10:19









                songyuanyao

                85k9163222




                85k9163222



























                     

                    draft saved


                    draft discarded















































                     


                    draft saved


                    draft discarded














                    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













































































                    Popular posts from this blog

                    How to check contact read email or not when send email to Individual?

                    Christian Cage

                    How to properly install USB display driver for Fresco Logic FL2000DX on Ubuntu?