模板参数推导因typedef失败?

时间:2018-11-10 19:12:44

标签: c++ class templates typedef

考虑以下两类:

startsWith()

当我尝试将类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<int,int>的对象时,出现以下编译错误:

B

是否有另一种方法可以使用typedef作为template argument deduction/substitution failed: couldn't deduce template parameter ‘_T’ 的输入参数?

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

问题在于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;
}

答案 2 :(得分:0)

我遇到了另一个错误(使用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不是实际类型,而是模板化的类型名。