相关疑难解决方法(0)

353
推荐指数
18
解决办法
30万
查看次数


在函数模板中使用静态局部变量的地址作为类型标识符是否安全?

我希望创建一个std::type_index不需要RTTI的替代方案:

template <typename T>
int* type_id() {
    static int x;
    return &x;
}
Run Code Online (Sandbox Code Playgroud)

请注意,局部变量的地址x用作类型ID,而不是其x自身的值.另外,我不打算在现实中使用裸指针.我刚刚删除了与我的问题无关的所有内容.在这里查看我的实际type_index实现.

这种方法听起来是否合理,如果是这样,为什么?如果没有,为什么不呢?我觉得我在这里不稳定,所以我对我的方法将会或不会起作用的确切原因感兴趣.

典型的用例可能是在运行时注册例程以通过单个接口处理不同类型的对象:

class processor {
public:
    template <typename T, typename Handler>
    void register_handler(Handler handler) {
        handlers[type_id<T>()] = [handler](void const* v) {
            handler(*static_cast<T const*>(v));
        };
    }

    template <typename T>
    void process(T const& t) {
        auto it = handlers.find(type_id<T>());
        if (it != handlers.end()) {
            it->second(&t);
        } else {
            throw std::runtime_error("handler not registered");
        }
    }

private:
    std::map<int*, …
Run Code Online (Sandbox Code Playgroud)

c++ templates rtti language-lawyer

40
推荐指数
4
解决办法
2384
查看次数

你能切换一个 std::any.type() 吗?

我想探索如何使用std::any而不是 void * 或此类构造进行消息传递。所以我创建了一个示例代码来测试这个 - 见下文。

std::any 的使用看起来不错,但我想切换类型以检查 std::any 是哪种类型。这可能是不可能的,而且我知道我可以使用 if/elseif... 块来代替,但是如果我可以创建一个 switch 语句,以便我在具有 10-20 种不同类型的实际代码中使用它,那就太好了它会更具可读性。

#include <string>  
#include <iostream>  
#include <sstream>  
#include <any>  
#include <typeindex>  

struct ints { int a{1}; int b{2}; };
struct strings { std::string a{"string1"}; std::string b{"string2"}; };

void send_msg(std::any item)
{
    switch (item.type().hash_code())       // <------- HERE
    {
        case typeid(ints).hash_code():     // <------- HERE
            std::cout << "ints" << std::endl;
            break;
        case typeid(strings).hash_code():
            std::cout << "strings" << std::endl;
            break;
        default:
            std::cout << "unknown type\n";
    }
} …
Run Code Online (Sandbox Code Playgroud)

c++ any c++17

7
推荐指数
1
解决办法
237
查看次数

typeid(*this).name() 在 std::exception 子类的委托构造函数上返回空指针

运行用 clang 编译的这段小代码片段时,我发现了一个奇怪的行为:

#include <iostream>
#include <exception>
#include <typeinfo>

struct Foo : public std::exception {
    std::string myString;
    Foo(const std::string& str) : myString(str) {}
    Foo() : Foo(typeid(*this).name()) {}
};

int main()
{
    Foo f;
    std::cout << f.myString;
}
Run Code Online (Sandbox Code Playgroud)

typeid(*this).name()委托构造函数内部调用的指令返回nullptr导致分段错误的 a。在委托构造函数调用期间,std::exception基类尚未初始化,这似乎是此行为的原因。

我想知道这段代码是否由于某种原因格式不正确,或者这种行为是预期的。

我无法使用 g++ 重现此错误,其中代码运行良好。

仅当基类是 std::exception 时才会发生这种情况,在任何其他情况下,即使在 clang 上也能正常工作。

c++ inheritance exception language-lawyer clang++

6
推荐指数
1
解决办法
307
查看次数

为每种类型编译时间typeid

我想要一个constexpr可以为每个C ++类型返回唯一ID 的函数,如下所示:

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;
}
Run Code Online (Sandbox Code Playgroud)

但是我得到一个错误:

t.cpp: In function 'int main()':
t.cpp:23:69: error: conversion from pointer type 'typeid_t (*)() noexcept {aka long unsigned int (*)() noexcept}' to arithmetic type 'typeid_t {aka long unsigned int}' in a constant-expression
   ::std::cout << ::std::integral_constant<typeid_t, type_id<float>()>{} << ::std::endl;
                                                                     ^
t.cpp:23:69: note: in template argument for type 'long unsigned …
Run Code Online (Sandbox Code Playgroud)

c++ c++14

5
推荐指数
1
解决办法
4910
查看次数

在C++中编译时获取类型名称

我想获取类型名称并将其打印用于调试目的.我使用以下代码:

#include <cxxabi.h>

inline const char* demangle(const char *s) {
    abi::__cxa_demangle(s, 0, 0, NULL);
}

template<typename T>
inline const char* type_name() {
    return demangle(typeid(T).name());
}
Run Code Online (Sandbox Code Playgroud)

它运行良好,但我认为有一个不必要的运行时开销.有没有办法获得在编译时计算的类型id的人类可读形式?我在考虑这样的事情:

boost::mpl::type_name<MyType>::value
Run Code Online (Sandbox Code Playgroud)

哪个会返回类型名称的字符串常量.

作为(不是那么严格)相关的问题:是否可以使用boost :: mpl进行字符串处理?

c++ boost typeinfo boost-mpl

4
推荐指数
1
解决办法
4744
查看次数