C ++如何在为“new”类型专门化模板时预定义构造函数参数

时间:2018-01-16 10:53:14

标签: c++ templates template-specialization

我有一个模板类,在其构造函数中使用了一个名称。该名称应该是实际类型的名称,因此可以将其放入人类可读的列表中。

无论如何,我目前正在定义这样的类型:

typedef templateClass<someType> someTypeClass;

但是,为了使名称也是“someTypeClass”,我需要用户始终正确指定该名称。相反,我想要一些方法来强制构造函数参数始终是“someTypeClass”(对于那种特定类型的特殊化)。

name参数的目的是让您知道模板特化的名称。这是一个例子

template<class t>
class TemplateClass{
private:
    std::string name;
    t data;
public:
    TemplateClass(const char* name);
    /*Irrelevant*/
};
typedef TemplateClass<int> intType; //name should be "intType" but how can I force the name to be "intType" for this case? I dont want the user to have to type "intType" for every instance he wants to make
typedef TemplateClass<char> charType; //name should be "charType"

这是否可以通过某种可行的方式实现,还是有更好的方法来解决这个问题?

3 个答案:

答案 0 :(得分:1)

您可以将名称设为静态,并自行初始化。

/// <reference path="typings/jquery/jquery.d.ts" />
module StudentModule {
    export class Student {
        Id: number;
        Fname: string;
        Lname: string;
        Address: string;

        customer(callback: any) {
            $.getJSON("api/customers", callback);
        }
    }
}

请注意,使用这种方法,您可能希望将pptViewer.loadPPT(MainActivity.this,"/home/waheed/lab6.pptx"); 放在标题中并在.cpp中初始化

用例子说明我的说明

TemplateClass.hpp

template<class t>
class TemplateClass{
private:
    static const std::string name;
    t data;
public:
    TemplateClass();
    /*Irrelevant*/
}

typedef TemplateClass<int> intType;
template <>
const std::string TemplateClass<int>::name = "intType";

typedef TemplateClass<char> charType;
template <>
const std::string TemplateClass<char>::name = "charType";

TemplateClass.cpp

std::string TemplateClass<int>::name;

这里我们在.hpp中声明了特化变量,但是在.cpp中初始化它。否则,它将在您包含它的每个编译单元中初始化,并将获得多个定义错误。

附加说明

如果您使用的是C ++ 17,则可以使用新的#include <string> template<class t> class TemplateClass{ private: static const std::string name; t data; public: TemplateClass(); /*Irrelevant*/ } typedef TemplateClass<int> intType; template <> const std::string TemplateClass<int>::name; typedef TemplateClass<char> charType; template <> const std::string TemplateClass<char>::name; 并执行

#include "TemplateClass.hpp"

template <>
const std::string TemplateClass<int>::name = "intType";

template <>
const std::string TemplateClass<char>::name = "charType";

无需在.cpp文件中添加任何内容。

答案 1 :(得分:0)

你所寻找的东西需要反思,目前c ++在这方面的选择非常有限。

当涉及到当前标准时,RTTI和typeinfo基本上就是这样。无论它是否有用,我都会留给你。下面是一个示例如何将类型的文本信息绑定到类:

#include <iostream>
#include <typeinfo>
#include <string>

using namespace std;

template <typename T>
struct A {
    const char* name = typeid(T).name();
};

int main() {
    A<int> a_int;
    A<double> a_double;
    A<string> a_string;
    cout << a_int.name << "\n";
    cout << a_double.name << "\n";
    cout << a_string.name << "\n";
    return 0;
}

所以有两个至少有三个直接的缺点,链接解释了一下:

  1. 它不适用于所有类型。 type_info::name
  2. 该字段不是静态的,尽管人们可能期望它。它在运行时进行评估。这与1. constexpr-and-rtti
  3. 重合
  4. 这些名字被破坏了。 Unmangling the result of std::type_info::name
  5. 我认为你不能在这个时候做得更好。据说一些反思建议被评估,但这是一个相当遥远的未来恕我直言。

答案 2 :(得分:0)

将数据成员name声明为staticthis answer建议并假设编译器支持C ++ 11(以便能够使用模板别名 ):

#include <string>

template<class t>
class TemplateClass{
private:
    static const std::string name;
    t data;
public:
    TemplateClass();
    /*Irrelevant*/
};

#define DEFINE_COMPONENT(type, typename) \
template<> \
const std::string TemplateClass<type>::name = #typename; \
using typename = TemplateClass<type>

DEFINE_COMPONENT(int, intType);
DEFINE_COMPONENT(char, charType);

预处理器宏DEFINE_COMPONENT完成了创建相应模板别名的工作,其名称作为第二个参数传递,并初始化字符串成员name以进行相应的专业化。