如何在c ++中正确识别变量类型.我试过这个来识别一种变量:
int a = 5;
std::cout << typeid(a).name() << std::endl;
Run Code Online (Sandbox Code Playgroud)
而不是预期的输出int,它给你:
i
Run Code Online (Sandbox Code Playgroud)
我很困惑,为什么会发生这种情况..它只是给你一个你声明变量的类型的第一个字母.Int不是唯一的...也是这样的:
char a = 'A'
std::cout << typeid(a).name() << std::endl;
Run Code Online (Sandbox Code Playgroud)
有一个简单的解决方法吗?任何帮助,将不胜感激!
我正在尝试做类似以下的事情
enum types {None, Bool, Short, Char, Integer, Double, Long, Ptr};
int main(int argc, char ** args) {
enum types params[10] = {0};
void* triangle = dlopen("./foo.so", RTLD_LAZY);
void * fun = dlsym(triangle, ars[1]);
<<pseudo code>>
}
Run Code Online (Sandbox Code Playgroud)
伪代码就像
fun = {}
for param in params:
if param == None:
fun += void
if param == Bool:
fun += Boolean
if param == Integer:
fun += int
...
returnVal = fun.pop()
funSignature = returnval + " " + funName + "(" …Run Code Online (Sandbox Code Playgroud) 使用gcc,当我使用typeid请求对象/变量的类型时,我得到了与我期望在Windows上获得的type_info :: name方法不同的结果.我用Google搜索了一下,发现RTTI名称是特定于实现的.
问题是,我想获得一个类型的名称,因为它将在Windows上返回.是否有捷径可寻?
我已经读过Pimpl有利于二进制兼容性,接口有利于轻松切换实现.我需要结合这两种技术,以便我的应用程序能够通过配置文件切换底层实现.
以下是我当前设计的布局:
Foo类:提供面向客户的API,我很担心ABI兼容性这里
一流的IFoo:接口类(所有的纯虚方法,虚析构函数)
类Vendor1Foo:实现IFoo的,使用的供应商1的库
类Vendor2Foo:实现IFoo的,使用供应商2的图书馆
通过不使用pimpl并严格使用接口,客户端代码可能如下所示:
IFoo* foo = new Vendor1Foo();
Run Code Online (Sandbox Code Playgroud)
问题是我的客户端代码根本无法了解Vendor1或Vendor2,而Foo只是我必须执行此操作的众多类之一.
我正在尝试做的所有概念如下:
class foo
{
private:
QScopedPointer<IFoo> pimpl;
void initImpl(); // Reads from QSettings and initializes pimpl
}
Run Code Online (Sandbox Code Playgroud)
有什么想法可以优雅地解决这个问题吗?
我希望能够提出一些宏或模板类/方法来帮助标准化我如何处理这个并最大限度地减少违反DRY.
模板类可以作为一个辅助性PIMPL像香草萨特的大上广义PIMPL方法对C++ 11:herbsutter.com/gotw/_101,它也必须包含逻辑实例根据配置的正确实施
这里有pimpl成语,桥梁模式和工厂模式的元素.在上面的例子中,initImpl()可以被认为是一个工厂方法.我正在寻找可能会或可能不会使用所有这些模式的解决方案.
我已经看过c ++ pimpl习语:实现取决于模板参数以及SO上的大多数pimpl习语问题.标题似乎很有希望,但它对我的特定用例没有帮助.
我不能使用C++ 11并使用Qt. D-Pointers无法解决我的问题,因为它们绑定到单个实现.
问题很简单:如何在C++类中打印模板参数的名称并在编译时将其分配给类变量?似乎必须在运行时或至少某些部分评估both typeinfo(typeid)和boost :: typeindex.这显然不允许编译器完全解决constexpr包含对此函数之一的调用.
template<typename T>
class X
{
public:
static const char * name = /* SOME C++ code transforming T in a string (either std::string or char */
};
Run Code Online (Sandbox Code Playgroud)
我错过了什么?是否只能在运行时生成名称?在那种情况下,我真的需要一个实例化的对象吗?这对我来说似乎不对,因为以下完美的工作没有任何实例:
#include <iostream>
#include <string>
#include <boost/type_index.hpp>
using namespace std;
template<class T>
class X
{
public:
static std::string name()
{
return boost::typeindex::type_id<T>().pretty_name();
}
};
struct foobar {};
int main()
{
cout << X<int>::name() << endl;
cout << X<foobar>::name()<< endl;
}
Run Code Online (Sandbox Code Playgroud)
因此name(),我不想将其作为类变量,而是将其作为类变量.
目前我有:
template <typename T> struct typename_struct<T*> {
static char const* name() {
return (std::string(typename_struct<T>::name()) + "*").c_str();
}
};
Run Code Online (Sandbox Code Playgroud)
我想知道我是否可以避免在我被迫分配字符串来执行连接的整个位置.
这一切都发生在编译时,即我打算"int****"在引用时获取字符串typename_struct<int****>::name().(假设我已经声明了相应的int返回专门化"int")
在编写代码时,编译器是否仅在编译时使用std :: string进行串联?(我会好的)或者这样的调用会在运行时导致基于4 std :: string的连接吗?(我不会那么好)
这是一个复杂的过程,因为它也取决于Boost版本和平台。
我正在使用boost stacktrace在某些断言失败的地方打印backtrace。有一些外部编译时和运行时dep,具体取决于您使用的是哪种模式(链接介绍了〜5个模式)。我更喜欢基于调试信息和导出信息的东西(我认为后者也可以在生产版本中使用)。但是,我可以得到既不默认模式或工作BOOST_STACKTRACE_USE_ADDR2LINE或BOOST_STACKTRACE_USE_BACKTRACE-所有3只显示在我的实际的程序代码的调用堆栈地址-看到一个谷歌测试测试堆栈跟踪如下:
0# 0x000055E47D43BDC2 in Debug/myprog
1# 0x000055E47D489055 in Debug/myprog
2# 0x000055E47D567FDF in Debug/myprog
3# 0x000055E47D560CDE in Debug/myprog
4# void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) in /usr/lib/libgtest.so.1.8.1
5# testing::Test::Run() in /usr/lib/libgtest.so.1.8.1
6# testing::TestInfo::Run() in /usr/lib/libgtest.so.1.8.1
7# testing::TestCase::Run() in /usr/lib/libgtest.so.1.8.1
8# testing::internal::UnitTestImpl::RunAllTests() in /usr/lib/libgtest.so.1.8.1
Run Code Online (Sandbox Code Playgroud)
我尝试了什么:-rdynamic,-fno-pie和-fPIC,(我已经在-O0上),-ggdb3而不是默认的-g3,没有任何函数名称显示出来。
我正在使用:gcc 8.2,boost 1.69(stracktrace库的仅标头模式),Arch Linux(在该系统上,我必须手动安装未打包的libbacktrace,所以我更喜欢使用ADDR2LINE方法)
编辑:更新到最新的boost.stacktrace的链接。
Edit2:我注意到boost.stacktrace文档包含此提示
由于地址空间布局随机化,共享库中的函数名称可能无法解码。总比没有好。
...听起来很有帮助,但对我来说却是另一回事,我没有在自己的可执行文件中获取符号,但是libgtest.so例如。因此,好像调试信息设置有问题。任何想法表示赞赏。
使用XCode 3.2.3(64位),我得到以下奇怪的输出.我究竟做错了什么?
#include <iostream>
#include <typeinfo>
struct student {
};
int main()
{
int i;
student obj;
std::cout << typeid(i).name() << "\n";
std::cout << typeid(obj).name() << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
i
7student
Run Code Online (Sandbox Code Playgroud) 是否有编译器以可读的方式返回类型的名称(或提供该功能或工具的库)。基本上我想要的是与您在源代码中编写的类型表达式相对应的字符串。
存在依赖于以下事实的代码:创建返回值后,本地自动函数变量将被破坏,例如:
1)取消std :: type_info :: name的结果
std::string demangle(const char* name)
{
int status = -4;
std::unique_ptr<char, void(*)(void*)> res {
abi::__cxa_demangle(name, NULL, NULL, &status),
std::free
};
return (status==0) ? res.get() : name;
}
Run Code Online (Sandbox Code Playgroud)
class C {
mutable std::mutex _lock;
map<string,string> deep_member;
public:
auto get_big_lump()
{
std::unique_lock<std::mutex> lock(_lock);
return deep_member;
}
};
Run Code Online (Sandbox Code Playgroud)
标准在哪里指定要保证此订单?
我已经将磁盘文件读入内存到一个声明为:
char * buffer = new char [length];
Run Code Online (Sandbox Code Playgroud)
然后重新解释数组:
std::string strbuf(reinterpret_cast<const char *>(buffer), length);
Run Code Online (Sandbox Code Playgroud)
并立即检查提供的字符串的类型.
cout << "buffer is: " << typeid(buffer).name() << '\n';
cout << "strbuf is: " << typeid(strbuf).name() << '\n';
buffer is: Pc
strbuf is: Ss */
Run Code Online (Sandbox Code Playgroud)
如您所知,字符串"strbuf"的类型为Ss.那是什么意思?