【问题标题】:Template argument deduction failed with typedef?typedef 模板参数推导失败?
【发布时间】:2018-11-10 19:12:43
【问题描述】:

考虑以下几个类:

template <typename T1, typename T2>
class A{ 
public:
    // ...
};

template<typename _T>
struct alias { typedef A<int,_T> intA; };

class B{
public:
    // ...
    template <typename _T> B& operator=(const typename alias<_T>::intA& _arg) { };
};

当我尝试将 A&lt;int,int&gt; 类的对象分配给 B 类的对象时,出现以下编译错误:

template argument deduction/substitution failed: couldn't deduce template parameter ‘_T’

有没有其他方法可以使用 typedef 作为B::operator=() 的输入参数??

【问题讨论】:

  • 这不是问题,但是以下划线开头后跟大写字母 (_T) 的名称和包含两个连续下划线的名称保留供实现使用。不要在你的代码中使用它们。

标签: c++ class templates typedef


【解决方案1】:

模板化 using 可能会解决问题

template <typename T1, typename T2>
class A{ 
public:
    // ...
};

template<typename _T>
using alias = A<int,_T>;

class B{
public:
    // ...
    template <typename _T> B& operator=(const alias<_T>& ) { return *this; };
};

void f()
{
    B b;
    A<int, int> a;
    b = a;
}

【讨论】:

    【解决方案2】:

    问题在于intA 是一个从属名称。不能从依赖名称推导出模板。例如:Dependent Types: Template argument deduction failed

    您还缺少typename 关键字。

    您可以明确指定运算符的类型:

    template <typename T1, typename T2>
    struct A{ };
    
    template<typename _T>
    struct alias { typedef A<int,_T> intA; };
    
    struct B 
    {
        template <typename T> B& operator=(const typename alias<T>::intA& _arg) { };
    };
    
    int main() 
    {
        A<int,int> a;
        B b;
        b.operator=<int>(a);
        return 0;
    }
    

    或者您可以使用模板化别名(带或不带函数)获得特定的非依赖名称参数:

    template <typename T1, typename T2>
    struct A{ };
    
    template<class T>
    using alias_int = A<int, T>;
    
    struct alias
    {
        template<class T>
        using intA = A<int, T>;
    };
    
    struct B 
    {
        template <typename T> B& operator=(const alias_int<T>& _arg) { };
    };
    
    struct C
    {
        template <typename T> C& operator=(const alias::intA<T>& _arg) { };
    };
    
    int main() 
    {
        A<int,int> a;
        B b;
        C c;
        b = a;
        c = a;
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      我得到一个不同的错误(使用 g++ 5.4): need ‘typename’ before ‘alias&lt;_T&gt;::intA’ because ‘alias&lt;_T&gt;’ is a dependent scope 并且确实为我编译了以下内容:

      template <typename T1, typename T2>
      class A{ 
      public:
          // ...
      };
      
      template<typename _T>
      struct alias { typedef A<int,_T> intA; };
      
      class B{
      public:
          // ...
          template <typename _T> B& operator=(const typename alias<_T>::intA& _arg) { };
      };
      

      我认为原因是 alias&lt;_T&gt;::intA 不是实际类型,而是模板类型名。

      【讨论】:

      • 我忘记了代码示例中的 typename 关键字。如果相关,我正在尝试使用-std=c++11 进行编译。
      • 使用 -std=c++11 为我编译。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-26
      • 2012-12-06
      • 2020-06-05
      • 1970-01-01
      • 2018-04-28
      相关资源
      最近更新 更多