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?

                    Displaying single band from multi-band raster using QGIS

                    How many registers does an x86_64 CPU actually have?