Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 仅为一种类型专门化模板类成员函数_C++_Templates_Template Specialization - Fatal编程技术网

C++ 仅为一种类型专门化模板类成员函数

C++ 仅为一种类型专门化模板类成员函数,c++,templates,template-specialization,C++,Templates,Template Specialization,我有一个模板类,它有很多函数,但本质上是一个向量类。我只想在bool类型中添加一个函数 #include <vector> template <typename T> class reflected{ private: T*dev_; T*host_; ar_size size; reflected<T>& operator=(reflected<T>& rhs

我有一个模板类,它有很多函数,但本质上是一个向量类。我只想在bool类型中添加一个函数

#include <vector>
template <typename T>
class reflected{
    private:
        T*dev_;
        T*host_;
        ar_size size;
        reflected<T>& operator=(reflected<T>& rhs);//do not impliment.  assign not allowed.
        reflected( reflected<T>& old);  //do not impliment. Copy not allowed.
    public:
        reflected():size(0L),dev_(NULL),host_(NULL){}
        reflected(ar_size n):size(n),dev_(NULL),host_(NULL){init();}
        reflected(const T*x,ar_size n):size(n),dev_(NULL),host_(NULL){init();set(x);}
        ~reflected();
        void init();
        void init(ar_size n);
        void init(const T*x,ar_size n);
        void set(const T * x);
        void setat(ar_index i, T x);
        const T getat(ar_size i);
        const T * devPtr();
        const T operator [](const ar_index i);
        ar_size length(){return size;}
};
#包括
模板
阶级反映{
私人:
T*开发人员;
T*host_u2;;
ar_尺寸;
反射的&operator=(反射的&rhs);//不执行。不允许赋值。
反射(反射和旧);//不执行。不允许复制。
公众:
反射()
反射(ar_size n):大小(n)、开发(NULL)、主机(NULL){init();}
反射(const T*x,ar_size n):大小(n),开发(NULL),主机(NULL){init();集(x);}
~z~反射();
void init();
void init(ar_尺寸n);
void init(常数T*x,ar_大小n);
无效集(常数T*x);
无效集(ar_指数i,T x);
施工图(尺寸i);
常数T*devPtr();
常量T运算符[](常量ar_索引i);
ar_size length(){return size;}
};

我想在反射类的特殊情况下添加一个函数
vector reflected::which()
,这是唯一有意义的情况。最好的方法是什么。编译器似乎不喜欢将which()添加到reflected,而只为bool定义它。

如果只想添加一个问题,可以将继承与专门化结合起来:

template <typename T>
class reflected_base { 
    // your current 'reflected' contents go here
}; 

template <typename T>
class reflected : public reflected_base { };

template <>
class reflected<bool> : public reflected_base {
    vector<ar_index> which();
};
模板
类{u基{
//您当前的“反映”内容放在这里
}; 
模板
类反射:公共反射的_基{};
模板
类反射:公共反射\u基{
向量which();
};
这种方法的缺点是,您必须为每个专门化重新实现某些操作(析构函数、复制构造函数等)。另一种选择是:

template <typename T>
class specialized_reflected { };

template <>
class specialized_reflected<bool> {
public:
    vector<ar_index> which();
};

template <typename T>
class reflected : public specialized_reflected<T> {
    // your current 'reflected' contents go here
};
模板
类{};
模板
班级专业化{
公众:
向量which();
};
模板
反映的类别:反映的公共专业{
//您当前的“反映”内容放在这里
};
但是,依赖名称查找也存在潜在问题。第三种选择(我可能会选择)是使用非成员函数:

vector<ar_index> which(reflected<bool>&);
向量(反射&);

不能直接按您想要的方式完成。但是,您可以通过不为任何类定义
reflected()
,而获得类似的结果,专用类除外。如果您试图在不受支持的类上使用它,那么您将得到一个线性错误

#include <string>
#include <sstream>
using namespace std;

template<typename A>
class Gizmo
{
public:
    Gizmo(){};
    int which();    
};

template<> int Gizmo<bool>::which()
{
    return 42;
}

int main()
{

    Gizmo<bool> gb;
    gb.which();

    Gizmo<int> gi;
    gi.which(); // LINKER ERROR for Gizmo<int>which()

    return 0;
}
#包括
#包括
使用名称空间std;
模板
类Gizmo
{
公众:
Gizmo(){};
int which();
};
模板int Gizmo::which()
{
返回42;
}
int main()
{
Gizmo gb;
gb.which();
Gizmo-gi;
gi.which();//Gizmowhich()的链接器错误
返回0;
}

您可以像这样在类模板中定义它

template <typename T> struct id { typedef T type; };

template <typename T>
class reflected{
    private:
        /* ... */
        vector<ar_index> which(id<bool>) { 
          /* ... */
        }
    public:
        /* ... */
        vector<ar_index> which() { return which(id<T>()); }
};
模板结构id{typedef T type;};
模板
阶级反映{
私人:
/* ... */
(id){
/* ... */
}
公众:
/* ... */
向量which(){返回which(id());}
};

如果在未给出正确定义的
T
上调用
which
,则会出现编译时错误

您可以将
vector reflected::which()
添加到
reflected
(并且仅添加到它,而不添加到常规模板)。如果您出现错误,可能您没有正确地进行模板专门化…

+1
因为您以90秒的优势击败了我!您需要
在反射的声明中也为反射的\u基。但是,那么,为什么您确实需要reflected_base呢?@Diego:这样主要的
reflected
模板和
reflected
的每个专门化都可以使用相同的成员。也就是说,Johannes的答案远远优于(像往常一样…)@詹姆斯:但这可以通过将所需的函数添加到专门化
反射的
…snap!但我会将其描述为“将which()添加到reflected中,并仅为bool定义它”。OP说他正在这样做。我解释OP的描述,好像她试图为
bool
专门化重新定义类。重新阅读后,你可能是对的。如果OP回答这是他正在做的,我将删除它。这是我正在尝试的,它不起作用。编译器不喜欢它。我不确定他/她是否希望该方法失败,或者只是它没有定义,而是针对
bool
。无论如何,你的解决方案非常好:)这和约翰·迪布林的答案相比如何?额外的“间接性”有什么好处吗?Thanks@icecrime您不需要复制构造函数,它可以扩展。如果某些函数只对
int
有意义,而对其他函数没有意义,则不需要另一个派生类。我喜欢为此使用重载。@Johannes抱歉,我指的是John Dibling答案,它不依赖继承,而是依赖于只为反射的
定义的
方法specialization@icecrime哦,对不起,我读错了:)约翰没有给出编译时错误。它稍后将无法链接(对于一个大型项目来说,这可能要晚得多)。