如何将模板超类类型传递给模板基类?

时间:2013-11-10 01:39:25

标签: c++ templates

我正在尝试继承一个结构,以便添加一个+ =运算符。

这段代码似乎没错,但是编译失败了,我从编译器得到的就是:

  

语法错误:在'<'之前缺少','   请参阅正在编译的类模板实例化'Test'的引用

struct plus_equals
{
    template<typename T, typename S>
    struct operator_type
    {
        S& operator+=(const T &other)
        {
            S* super = (S*)this;
            super->value += other;
            return *super;
        }
    };
};

template<typename T, typename OP>
struct Test : OP::operator_type<T, Test<T, OP>>   // error on this line
{
    T value;
    Test(T val) : value(val){}
};

int main(int argc, char *argv[])
{
    Test<int, plus_equals> test(123);
    test += 456;
    cout << test.value << endl;
    return 0;
}

我很困惑为什么下面的代码会编译,但上面的代码不会。

template<typename T>
struct Something
{
    T GetT() { return T(); }
};

class Test : public Something<Test>
{
    //...
};

2 个答案:

答案 0 :(得分:1)

您的代码存在的问题是operator_type是一个模板,但编译器不知道将它视为一个模板,除非您将模板关键字放在它前面。

#include <iostream>                                                                
using namespace std;                                                               
struct plus_equals                                                                 
{                                                                                  
    template<typename T, typename S>                                               
    struct operator_type                                                           
    {                                                                              
        S& operator+=(const T &other)                                              
        {                                                                          
            S* super = (S*)this;                                                   
            super->value += other;                                                 
            return *super;                                                         
        }                                                                          
    };                                                                             
};                                                                                 

template<typename T, typename OP>                                                  
struct Test : OP:: template operator_type<T, Test<T, OP>>   // error on this line
{                                                                                  
    T value;                                                                       
    Test(T val) : value(val){}                                                     
};                                                                                 

int main(int argc, char *argv[])                                                   
{                                                                                  
    Test<int, plus_equals> test(123);                                              
    test += 456;                                                                   
    cout << test.value << endl;                                                    
    return 0;                                                                      
}   

这个question解释了如何完全解决依赖模板和类型名称问题再次出现。我还建议升级你的编译器作为clang 3.3基本上用勺子喂你错误。这是我得到的很好的清洁错误。 enter image description here

这是一个很多更简单的问题解决方案

#include <iostream>                                                                
using namespace std;                                                               
template<typename T, typename Orig>                                                
struct operator_type                                                               
{                                                                                  
    Orig & operator+=(const T &other)                                              
    {                                                                              
        static_cast<Orig*>(this)->value += other;                                   
        return *static_cast<Orig*>(this);                                           
    }                                                                              
};                                                                                 

template<typename T, template <class,class> class OP>                               
struct Test : OP<T,Test<T,OP>>   // error on this line                             
{                                                                                  
    T value;                                                                       
    Test(T val) : value(val){}                                                     
};                                                                                 

int main() {                                                                       
    Test<int,operator_type> t(10);                                                 
    t += 10;                                                                       
    cout << t.value << endl;                                                       
    return 0;                                                                      
}

答案 1 :(得分:1)

如果您使用template关键字消除歧义,则会进行编译。

struct Test : OP::template operator_type<T, Test<T, OP> >

为什么这有必要包括在这里:Disambiguator template keyword for a template member of a template: when exactly?