I have following code:
enum class type
{
zero,
one,
two
};
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 F, typename K, typename... T>
void rec(int j, F &f, ps<K> const &s0, T const &... t) // 3
{
auto [n, v] = s0;
f(j, n, v);/*pro*/
rec<B>(j, f, t...);
}
template <typename B, typename F, typename K, typename... T>
void rec(int j, F &f, pv<K> const &t0, ps<K> const &s0, T const &... t) // 2
{
auto [n, v] = t0;
for(auto k : v) {
rec<B>(j, f, s0, t..., ps<K>{n, k});
}
}
template <typename B, typename F, typename K, typename... T>
void rec(int j, F &f, pv<K> const &t0, T const &... t) // 1
{
auto [n, v] = t0;
for(auto k : v) {
rec<B>(j, f, t..., ps<K>{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;
}
This compiles fine with clang++ (clang version 6.0.0-1ubuntu2) but fails with g++ (g++ (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0). GCC throws the following error:
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::pair<type, std::vector<std::__cxx11::basic_string<char> > >, std::pair<type, std::vector<std::__cxx11::basic_string<char> > >)’ is ambiguous
rec<char>(j, pro, pv<std::string>{type::zero, v0}, pv<std::string>{type::one, v1}, pv<std::string>{type::two, v2});
^
main.cpp: note: candidate: void rec(int, F&, ps<K>&, const T& ...) [with B = char; F = void(int, type, 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::char_traits<char>, std::allocator<char> > > > >, 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::char_traits<char>, std::allocator<char> > > > >}; ps<K> = std::pair<type, std::vector<std::__cxx11::basic_string<char> > >]
void rec(int j, F &f, ps<K> const &s0, T const &... t) // 3
^~~
main.cpp: note: candidate: void rec(int, F&, pv<K>&, const T& ...) [with B = char; F = void(int, type, const std::__cxx11::basic_string<char>&); K = 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::char_traits<char>, std::allocator<char> > > > >, 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::char_traits<char>, std::allocator<char> > > > >}; pv<K> = std::pair<type, std::vector<std::__cxx11::basic_string<char> > >]
void rec(int j, F &f, pv<K> const &t0, T const &... t) // 1
^~~
Why are the functions at comment 1
and comment 3
ambiguous even though the parameter types pv
and ps
are different?
Interestingly, the following code works with both clang++ and g++ (note the removal of template parameter B
from functions rec
):
enum class type
{
zero,
one,
two
};
template <typename K>
using pv = std::pair<type, std::vector<K>>;
template <typename K>
using ps = std::pair<type, K>;
template <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 F, typename K, typename... T>
void rec(int j, F &f, ps<K> const &s0, T const &... t) // 3
{
auto [n, v] = s0;
f(j, n, v);/*pro*/
rec(j, f, t...);
}
template <typename F, typename K, typename... T>
void rec(int j, F &f, pv<K> const &t0, ps<K> const &s0, T const &... t) // 2
{
auto [n, v] = t0;
for(auto k : v) {
rec(j, f, s0, t..., ps<K>{n, k});
}
}
template <typename F, typename K, typename... T>
void rec(int j, F &f, pv<K> const &t0, T const &... t) // 1
{
auto [n, v] = t0;
for(auto k : v) {
rec(j, f, t..., ps<K>{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(j, pro, pv<std::string>{type::zero, v0}, pv<std::string>{type::one, v1}, pv<std::string>{type::two, v2});
return 0;
}
Why does the second code work with g++ but not the first?
Aucun commentaire:
Enregistrer un commentaire