【问题标题】:Ambiguity error in C++17 (template template parameters and default arguments issue)C++17 中的歧义错误(模板模板参数和默认参数问题)
【发布时间】:2019-01-24 08:45:19
【问题描述】:

我的代码使用 c++14c++17 标准标志被 g++ 以不同方式解释:

#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;
}

当我尝试使用命令编译此代码时

g++ -std=c++14 -Wall -pedantic main.cpp

一切正常。

但是当我试图用命令编译这段代码时

g++ -std=c++17 -Wall -pedantic main.cpp

我收到此错误:

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)

从 C++17 标准的角度来看,我无法弄清楚这段代码有什么问题。

【问题讨论】:

    标签: c++ templates c++14 language-lawyer c++17


    【解决方案1】:

    自 C++17 以来行为发生了变化。

    在 C++17 之前,代码可以工作,因为std::vector 有两个模板参数(第二个有默认参数std::allocator&lt;T&gt;),而模板模板参数Vector 被声明只有一个,它们没有'不匹配则不考虑第二个func

    自 C++17 (CWG 150) 起,template template argument 允许使用默认模板参数来匹配具有较少模板参数的模板模板参数。这意味着func 都成为有效的候选人,然后导致歧义。

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-12
      • 2015-08-15
      • 2015-05-09
      • 2018-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多