使用 typedef 模板参数推导失败?

Template argument deduction failed with typedef?

考虑以下几个 classes:

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) { };
};

当我尝试将 class A<int,int> 的对象分配给 class B 的对象时,出现以下编译错误:

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

是否有其他方法可以使用某种类型定义作为 B::operator=() 的输入参数??

模板化 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;
}

我遇到了不同的错误(使用 g++ 5.4): need ‘typename’ before ‘alias<_T>::intA’ because ‘alias<_T>’ 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<_T>::intA 不是实际类型而是模板化的类型名。

问题是 intA 是从属名称。不能从相关名称中推导出模板。参见示例:.

您还缺少 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;
}