编译每种类型的时间typeid

时间:2016-03-20 18:38:51

标签: c++ c++14

我想要一个SELECT barcode FROM table1 where name like 'abc%' 函数,它会为每个C ++类型返回一个唯一的id,如下所示:

constexpr

但是我收到了一个错误:

using typeid_t = uintptr_t;

template <typename T>
constexpr typeid_t type_id() noexcept
{
  return typeid_t(type_id<T>);
}

int main()
{
  ::std::cout << ::std::integral_constant<typeid_t, type_id<float>()>{} << ::std::endl;

  return 0;
}

是否有解决方法或其他方式?

3 个答案:

答案 0 :(得分:3)

您可以使用此answer中显示的一些技巧。

甚至还有一个名为ctti的库使用相同的技巧,它应该可以开箱即用

WebView

答案 1 :(得分:2)

另一种方式,这次涉及constexpr函数,将使用一个众所周知的哈希函数,如下例所示(我使用FNV v1a):

#include <cstdint>
#include <iostream>

static constexpr uint32_t offset = 2166136261u;
static constexpr uint32_t prime = 16777619u;

constexpr uint32_t helper(uint32_t partial, const char *str) {
    return str[0] == 0 ? partial : helper((partial^str[0])*prime, str+1);
}

constexpr uint32_t hash_str(const char *input) {
    return helper(offset, input);
}

struct MyClassA { static constexpr uint32_t type = hash_str("MyClassA"); };
struct MyClassB { static constexpr uint32_t type = hash_str("MyClassB"); };

int main() {
    std::cout << "MyClassA: " << MyClassA::type << std::endl;
    std::cout << "MyClassB: " << MyClassB::type << std::endl;
}

缺点:

  • 可能发生冲突
  • 容易出错(至少从我的角度来看)
  • 非常侵入性的溶解

主要优点是,如果您需要在不同的执行中使用相同的类型,则可以使用此解决方案(例如,如果您必须将它们存储在某处并在一段时间后再次使用它们)。

答案 2 :(得分:1)

这不是constexpr函数,但是如果没有对多个执行持久化的类型的约束,则可以使用CRTP idiom作为替代方法来实现相同的结果。<登记/> 它遵循一个最小的工作示例:

#include <cstddef>
#include <iostream>

struct BaseClass {
protected:
    static std::size_t next() noexcept {
        static std::size_t counter = 0;
        return counter++;
    }
};

template<class D>
struct Base: public BaseClass {
    static std::size_t type() noexcept {
        static std::size_t type_ = BaseClass::next();
        return type_;
    }
};

struct A: public Base<A> { };
struct B: public Base<B> { };

int main() {
    std::cout << A::type() << std::endl;
    std::cout << B::type() << std::endl;
}

这样你就有了一个基类,可以从中导出你想拥有唯一标识符的所有类型。