可变参数模板,谁是对的?是GCC还是Clang?

问题描述

我有以下代码:

enum class type
{
        zero,one,two
};

std::ostream& operator<<(std::ostream &os,type const &t)
{
        switch(t)
        {
                case type::zero: os << "zero"; break;
                case type::one: os << "one"; break;
                case type::two: os << "two"; break;
                default: os.setstate(std::ios_base::failbit);
        }

        return os;
}


template <typename K>
using pv = std::pair<type,std::vector<K>>;

template <typename K>
using ps = std::pair<type,K>;


template <typename B,typename F,typename K>
void rec(int j,F &f,ps<K> const &s0) // 4
{
        auto [n,v] = s0;
        f(j,n,v);/*pro*/
        std::cout << std::endl;
}

template <typename B,typename K,typename... T>
void rec(int j,ps<K> const &s0,T const &... t) // 3
{
        auto [n,v);/*pro*/
        rec<B>(j,f,t...);
}

template <typename B,pv<K> const &t0,T const &... t) // 2
{
        auto [n,v] = t0;
        for(auto k : v) {
                rec<B>(j,s0,t...,ps<K>{n,k});
        }
}

template <typename B,T const &... t) // 1
{
        auto [n,k});
        }
}

void pro(int j,type t,std::string const &s)
{
        std::cout << j << ":" << t << ":" << s << ",";
}

int main()
{
        std::vector<std::string> v0{"V00","V01"};
        std::vector<std::string> v1{"V10","V11"};
        std::vector<std::string> v2{"V20","V21"};

        int j = 0;

        rec<char>(j,pro,pv<std::string>{type::zero,v0},pv<std::string>{type::one,v1},pv<std::string>{type::two,v2});

        return 0;
}

使用clang ++(clang版本6.0.0-1ubuntu2)可以正常编译,但是使用g ++(g ++(Ubuntu 7.5.0-3ubuntu1〜18.04)7.5.0)可以正常编译。 GCC引发以下错误:

main.cpp: In function ‘int main()’:
main.cpp: error: call of overloaded ‘rec<char>(int&,void (&)(int,type,const string&),std::pair<type,std::vector<std::__cxx11::basic_string<char> > >,std::vector<std::__cxx11::basic_string<char> > >)’ is ambiguous
  rec<char>(j,v2});
                                                                                                                   ^
main.cpp: note: candidate: void rec(int,F&,ps<K>&,const T& ...) [with B = char; F = void(int,const std::__cxx11::basic_string<char>&); K = std::vector<std::__cxx11::basic_string<char> >; T = {std::pair<type,std::vector<std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::allocator<std::__cxx11::basic_string<char,std::allocator<char> > > > >,std::allocator<char> > > > >}; ps<K> = std::pair<type,std::vector<std::__cxx11::basic_string<char> > >]
 void rec(int j,T const &... t) // 3
      ^~~
main.cpp: note: candidate: void rec(int,pv<K>&,const std::__cxx11::basic_string<char>&); K = std::__cxx11::basic_string<char>; T = {std::pair<type,std::allocator<char> > > > >}; pv<K> = std::pair<type,T const &... t) // 1
      ^~~

即使参数类型13不同,为什么注释pv和注释ps的函数还是模棱两可的?

有趣的是,以下代码可用于clang ++和g ++(请注意,已从函数B中删除了模板参数rec):

enum class type
{
        zero,type const &t)
{
        switch(t)
        {
                case type::zero: os << "zero"; break;
                case type::one: os << "one"; break;
                case type::two: os << "two"; break;
                default: os.setstate(std::ios_base::failbit);
        }

        return os;
}

template <typename K>
using pv = std::pair<type,K>;


template <typename F,v);/*pro*/
        std::cout << std::endl;
}

template <typename F,v);/*pro*/
        rec(j,t...);
}

template <typename F,v] = t0;
        for(auto k : v) {
                rec(j,k});
        }
}

template <typename F,"V21"};

        int j = 0;

        rec(j,v2});

        return 0;
}

为什么第二个代码不能与g ++一起使用?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...