2016-04-16 43 views
1

我不知道应该如何进行模板专业化。这一次,不幸的是,谷歌和SO不能帮助我。在派生的模板类中专门设置一个基类的方法

对于基类:

class base 
{ 
public: 
    virtual ~base() = 0; 

    virtual int getInt() { throw std::invalid_argument(std::string(typeid(*this).name()) + " can't return int"); } 
}; 
base::~base() {} 

和派生类:

template<class T> 
class derived : public base 
{ 
public: 
    derived() {} 
    derived(T value) { mValue = value; } 

private: 
    T mValue; 
}; 

此代码:

void proof(base* arg) 
{ 
    try 
    { 
     std::cout << arg->getInt(); 
    } 
    catch (std::exception& e) 
    { 
     std::cout << e.what(); 
    } 
    std::cout << "\n\n"; 
} 

int main() 
{ 
    base* a = new derived<int>(23); 
    base* b = new derived<std::string>("abc"); 

    proof(a); 
    proof(b); 

    delete a; 
    delete b; 

    return 0; 
} 

输出,如果是不是已经明显:

class derived<int> can't return int 

class derived<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > can't return int 

我应该如何进行派生的专门化,所以getInt()会返回mValue?例如:

template<> 
int derived<int>::getInt() { return mValue; } 

这是行不通的。我想调用arg-> getInt()和我调用arg-> getInt()时抛出的基类中的异常,我希望pe输出为23。 你能给我一个示例代码吗?谢谢。

+0

即默认构造函数看起来像一个可怕的想法!这是什么意思*? –

+0

我想封装一些数据类型,所以我可以制作多种数据类型的矢量。注意:int只是一个例子,我确实有另外一些类不包含primite类型。 –

回答

1

derived模板没有getInt()方法。你不能专门化不存在的东西。

你必须专门化整个模板。试试这个:

template<> 
class derived<int> : public base 
{ 
public: 
    derived() {} 
    derived(int value) { mValue = value; } 
    int getInt() override { return mValue; } 
private: 
    T mValue; 
}; 
+0

如果这是唯一的解决方案,那么我将不得不一遍又一遍地为封装做类。这正是我不想做的事:写同一班10次,但使用不同的数据类型。感谢您的帮助。你确定这是唯一的方法吗? –

+0

是的,这就是专业化在C++中的工作原理。我相信还有其他设计类层次结构的方法可以以不同的方式使用专业化。例如,您可以创建“template class not_really_derived:public base {};”,专门为您的getInt()专门设计“not_really_derived ”,然后派生子类not_really_derived 而不是基础,没有专门化。 –

1

你可以专门的模板,int

template <> class derived<int> : public base 
{ 
public: 
    derived(int value) : mValue(value) {} 

    int getInt() override { return mValue; } 

private: 
    int mValue; 
}; 
+0

谢谢你帮助我。但是,不是另一种解决方案,所以我可以只专注于该功能? –

+0

@AndreiAndrey:你总是可以通过中间辅助基类将这个模式考虑进去,所以你不必重复任何通用的代码。这只是一个蛋糕的成分,你仍然必须带来所有其他的。 –

+0

去找鸡,所以我会得到鸡蛋。谢谢。 –