使用函数地址的模板类的唯一数字 ID

发布于 2024-08-19 11:31:18 字数 669 浏览 9 评论 0原文

所以,这个问题之前已经被问过,但我想要一个标题中包含一些关键词的问题。

问题很简单:如何才能拥有一个模板类,以便对于模板的每个实例(而不是类的每个实例)都有一个唯一的数字标识符?

也就是说,一种区分方法:

foo<int> f1;
foo<char> f2;
classID(f1) != classID(f2);

但是,

foo<int> f3;
foo<int> f4;
classID(f3) == classID(f4);

相关于:

在C++中,如何使用单例来确保每个类都有唯一的积分ID?

将唯一数字标识符分配给模板类的实例

So, this question has been asked before, but I wanted a question with some of those key words in the title.

The issue is simple: How can I have a templated class, such that for each instance of the template - but not each instance of the class - there is a unique, numerical identifier?

That is, a way to differentiate:

foo<int> f1;
foo<char> f2;
classID(f1) != classID(f2);

but,

foo<int> f3;
foo<int> f4;
classID(f3) == classID(f4);

Related to:

in C++, how to use a singleton to ensure that each class has a unique integral ID?

Assigning Unique Numerical Identifiers to Instances of a Templated Class

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

药祭#氼 2024-08-26 11:31:18
template<class T>
class Base
{
public:
    static void classID(){}
private:
    T* t;
};

int main()
{
    Base<int> foo;
    Base<int> foo2;
    Base<char> foo3;

    /*
    unsigned int i  = reinterpret_cast<unsigned int>(Base<int>::classID);
    unsigned int ii = reinterpret_cast<unsigned int>(Base<char>::classID);
    unsigned int iii = reinterpret_cast<unsigned int>(Base<int>::classID);
    /*/
    unsigned int i  = reinterpret_cast<unsigned int>(foo.classID);
    unsigned int ii  = reinterpret_cast<unsigned int>(foo2.classID);
    unsigned int iii  = reinterpret_cast<unsigned int>(foo3.classID);
    //*/

    return ((i != ii) + (i <= ii) + (i >= ii)) == 2;
}

就是这样!它是轻量级的,超级简单,并且不使用RTTI,尽管它使用了极其不安全的reinterpret_cast。

虽然,也许我错过了什么?

template<class T>
class Base
{
public:
    static void classID(){}
private:
    T* t;
};

int main()
{
    Base<int> foo;
    Base<int> foo2;
    Base<char> foo3;

    /*
    unsigned int i  = reinterpret_cast<unsigned int>(Base<int>::classID);
    unsigned int ii = reinterpret_cast<unsigned int>(Base<char>::classID);
    unsigned int iii = reinterpret_cast<unsigned int>(Base<int>::classID);
    /*/
    unsigned int i  = reinterpret_cast<unsigned int>(foo.classID);
    unsigned int ii  = reinterpret_cast<unsigned int>(foo2.classID);
    unsigned int iii  = reinterpret_cast<unsigned int>(foo3.classID);
    //*/

    return ((i != ii) + (i <= ii) + (i >= ii)) == 2;
}

That's how! It's lightweight, super easy, and doesn't use RTTI, although it uses the ridiculously unsafe reinterpret_cast.

Although, maybe I'm missing something?

潇烟暮雨 2024-08-26 11:31:18

我认为你可以为此使用一个静态函数,并继承它的类:

struct IdCounter { static int counter; };
int IdCounter::counter;

template<typename Derived>
struct Id : IdCounter {
  static int classId() {
    static int id = counter++;
    return id;
  }
};

struct One : Id<One> { };
struct Two : Id<Two> { };

int main() { assert(One::classId() != Two::classId()); }

当然,这不会是一个静态编译时常量 - 我认为这是不可能自动实现的(你必须手动将这些类型添加到一些类型列表,例如 mpl::vector )。请注意,如果只是比较类型的相等性,则不需要所有这些。您只需要使用 is_same (在 boost 和其他库中找到并且编写起来很简单),它会产生一个编译时间常数

template<typename A, typename B>
struct is_same { static bool const value = false; };
template<typename A> 
struct is_same<A, A> { static bool const value = true; };

int main() { char not_true[!is_same<One, Two>::value ? 1 : -1]; }

I think you can just use a static function for this, and inherit its class:

struct IdCounter { static int counter; };
int IdCounter::counter;

template<typename Derived>
struct Id : IdCounter {
  static int classId() {
    static int id = counter++;
    return id;
  }
};

struct One : Id<One> { };
struct Two : Id<Two> { };

int main() { assert(One::classId() != Two::classId()); }

Of course, that won't be a static compile time constant - i don't think that is possible automatically (you would have to add those types manually to some type list like mpl::vector). Please notice that for just comparing types for equality, you don't need all this. You just need to use is_same (found in boost and other libraries and trivial to write) which yields a compile time constant

template<typename A, typename B>
struct is_same { static bool const value = false; };
template<typename A> 
struct is_same<A, A> { static bool const value = true; };

int main() { char not_true[!is_same<One, Two>::value ? 1 : -1]; }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文