2016-07-10 49 views
0

我想实现一个C++程序,给定一个元素列表,打印出列表中的独特元素。C++ - 帮助理解功能和类模板之间的差异

我知道C比C++好很多,但我现在开始在C++ 上实际上只有(编码)。

我只读过C++概念,模板是什么,我对函数模板感到满意,但是我只是读了类模板,我想我对使用哪一个应用感到困惑到下面的场景。

这是我到目前为止已经写(*注意:函数isUnique设置应该是做别的事情,但现在我正在写里面只是​​核实的行动为):

cppArrays.h

#include <iostream> 
#include <cstdlib> 
#include <vector> 
#include <string> 
using namespace std; 

template <class T> class cpparray{ 
private: 
    int size; 
    vector<T> elems; 
public: 
    cpparray(int); 
    ~ cpparray(); 
    int isUnique(T arr); 
}; 


template <class T> cpparray<T>::cpparray(int size) 
{ 
    vector<T> elems(size); 
    cout << "Object created with size " << elems.size()<< "\n"<< endl; 
} 
template <class T> cpparray<T>::~cpparray() 
{ 
    cout << "Object del\n" << endl; 
} 

template <class T> int cpparray<T>::isUnique(T arr) 
{ 
    return arr.size(); 
} 

cppArrays.cc

#include "cppArrays.h" 

int main() 
{ 
    cpparray<int> a(10) ; 
    //a.push_back(1); 
    //a.push_back(2); 
    //cout << a.size() << a.begin() << a.end() << endl; 
    int b = isUnique(a); 
    return 0; 
} 

详细

[1]我试图使用模板,因为我希望我矢量能够与任何数据类型被实例化 - 炭/浮点/ INT。

[2]余认识到,在使用类模板,通过调用

cpparray<int>a(10); 

我最终声明一个对象类的一个“cpparray”,其类型为整数。它是否正确? 如果是,那么a.push_back(1)将无法​​正常工作,因为它没有引用成员变量,但对象本身,因此它是可以理解的我会得到一个编译时错误没有成员名为push_back在cpparray

但是,这使它更难我

[1]了解什么时候使用模板,而不是功能模板,

[2]如何初始化此矢量在模板类和工作与它,给我的目标?

+0

'push_back'应该存在作为array'的'的成员函数。然后[this](http://stackoverflow.com/questions/926752/why-should-i-prefer-to-use-member-initialization-list)。你的构造函数中的elems是一个本地实例。 – LogicStuff

+0

正确。但我试图使用std容器向量,但我搞乱了我尝试推广类数组以处理任何类型的数据向量的部分。 – Raaj

+0

我想说的是,在初始化尝试的情况下,你会搞砸C++入门书中模板之前的部分。并要求*“类模板vs函数模板”*有点像*“class vs function”*。 – LogicStuff

回答

2

你的构造应该使用初始化列表初始化成员,

这样的:

template <class T> array<T>::array(int sz) : size(sz), elems(sz) 
{ 
    cout << "Object created with size " << elems.size()<< "\n"<< endl; 
} 

你做什么是声明向量作为构造的地方,它初始化大小,和当地矢量在块的末尾被摧毁。

2

当您需要一个具有编译时变量属性的通用类型时,请使用类模板。模板参数可以是类型常数,例如,

template<typename T, size_t Size> 
class MyArray { 
    T elements_[Size]; 
public: 
    MyArray() {} 
    // ... 
}; 

使用函数模板时,希望编写可应用于各类/参数的泛型函数:

#include <cstdio> 
#include <iostream> 

template<size_t BufSize, typename... Args> 
int strprintf(char(&buf)[BufSize], const char* fmt, Args&&... args) 
{ 
    static_assert(BufSize > 0, "Buffer too small"); 
    static_assert(BufSize < (1 << 31), "Buffer too large"); 
    return snprintf(buf, BufSize, fmt, std::forward<Args>(args)...); 
} 

int main() { 
    char buf[16]; 
    int printed = strprintf(buf, "hello world %s so long", "oversized load"); 
    std::cout << buf << "\n"; 
} 

http://ideone.com/SLUQX3

以上是如何可以替换的例子那些旧的vsnprintf转发printf类型函数之一;在编译时做所有的工作使得它更加高效。

BufSize可以由编译器推导出来,因为buf的类型是​​;它可以捕获由参考源,该类型是炭和数组大小 - 模板变量 - 是16.

它也可能有一个模板类的模板的成员函数:

template<typename T> 
class Foo { 
    T t_; 
public: 
    Foo() : t_() {} 
    Foo(const T& t) : t_(t) {} 

    template<typename RhsT> 
    bool is_same_size(const RhsT& rhs) { 
     return t_.size() == rhs.size(); 
    } 
}; 

这例子将只用于例证中工作时T和RhsT的尺寸()成员功能,导致以下:

Foo<vector<int>> fvi; 
Foo<list<double>> fld; 
fvi.is_same_size(fld); // fine 
Foo<int> fi; 
fvi.is_same_size(fi); // compiler error