假设我使用了一些C或C++库,它们是由标题和一些源文件组成的,它们被编译成我可以链接的静态或共享库.
在库的标题中(数十个......或数百个文件),定义了一些宏/符号.
现在我想在一个项目中使用这个库,它也定义了一些宏和符号.当然,我想避免名称冲突,因为有时会报告,特别是对于windows.h.但更一般地说,我希望控制从该标题中真正导出的内容.
我可以使用gcc预处理器选项生成已定义符号的列表:
gcc -E -dM include/great_lib.h | sort -V >symbols.txt
Run Code Online (Sandbox Code Playgroud)
这在文件symbols.txt中输出包含该标题时包含在用户文件中的所有定义符号的排序列表.
但是,它只给出符号,而不是给定义它的文件.
我觉得这可能是一个有用的信息.例如,检查是否在"great_lib.h"或其优先级中重新定义了某个系统宏.不幸的是,在检查gcc预处理器选项后,我没有看到使用gcc的方法.
例如,而不是只给我:
#define M_PI 3.14159265358979323846
Run Code Online (Sandbox Code Playgroud)
它会产生
#define M_PI 3.14159265358979323846; /usr/include/math.h
Run Code Online (Sandbox Code Playgroud)
也许是-dN选项的东西?但它的输出对我来说很困惑,它需要进一步的文本处理,我不明白信息是如何分层的.还是更简单的方法?
相关问题:
我在代码下面编译错误.
struct B{
double operator()(){
return 1.0;
}
};
struct A {
auto func() -> decltype(b())
{
return b();
}
B b;
};
Run Code Online (Sandbox Code Playgroud)
但是,如果我重组A
,它会编译.
gcc 4.8表示'b'未在此范围内声明.
struct A {
B b;
auto func() -> decltype(b())
{
return b();
}
};
Run Code Online (Sandbox Code Playgroud)
那么,第一个出了什么问题?
我正在使用boost :: geometry 的Rtree实现来存储(大量)2D点.现在我需要做距离最近的neigbors查询.
但是,本手册仅将查询描述为矩形框(即"获取此矩形内的所有点")或"KNN"查询("从此处获取最近的'n'点).
我想要的实际上是"让我得到距离小于'n'的点集."
我注意到你可以定义一元谓词,但是是......一元(因此,不适合两点的条件).
手册记录了model::ring
我认为最初可能适合圆形的一些类,但它实际上更像是一种分段线(多边形).这个假设是否正确?
有没有其他方法来处理这样的查询?或者它根本不可能?
我只是在自己的代码中注意到了这种行为,所以这是一个天真的问题:
这个:
struct A
{
int get()
{
return a;
}
int a=1;
};
int main() {}
Run Code Online (Sandbox Code Playgroud)
编译当然很好,虽然当成员数据的声明谎言之后的函数定义.
但后来我不明白为什么这样:
struct A
{
auto get() -> decltype(a)
{
return a;
}
int a=1;
};
Run Code Online (Sandbox Code Playgroud)
不编译(*).我要写这个:
struct A
{
int a=1;
auto get() -> decltype(a)
{
return a;
}
};
Run Code Online (Sandbox Code Playgroud)
有什么语言相关的原因,为什么它不好,或者只是编译器没有实现它?无论类成员的顺序如何,我都希望有相同的行为.
(*)通过Ideone.com使用gcc 6.3进行测试
考虑第三方库中的一个自由函数,它需要一个std::vector
as参数:void foo( std::vector<sometype>& );
现在,我在这个类型周围编写一个包装器,这样我就可以添加成员函数了.为了能够使用foo()
该类型,我添加了一个访问功能.
class Wrapper
{
private:
std::vector<sometype> _data;
public:
std::vector<sometype>& data() { return _data; }
const std::vector<sometype>& data() const { return _data; }
//... other stuff
};
Run Code Online (Sandbox Code Playgroud)
这样,我仍然可以使用foo()
:
Wrapper a;
foo( a.data() );
Run Code Online (Sandbox Code Playgroud)
但现在考虑另一个函数,它需要一个矢量向量sometype
(编辑:并将元素添加到该向量中):
void bar( std::vector<std::vector<sometype>>& );
Run Code Online (Sandbox Code Playgroud)
但我的数据类型是 std::vector<Wrapper> vec;
有没有办法使用我的包装类型来调用bar()
?
我想要做的是:
std::vector<Wrapper> vec;
bar( ??? );
Run Code Online (Sandbox Code Playgroud)
我想避免的一点是先调用bar()
所需的类型,然后逐个将元素复制到我的中vector<Wrapper>
.
起初,我会说"不",但也许有一些聪明的解决方案?
编辑2:举个例子,考虑以下玩具实现bar()
的int
root数据类型:
void bar( std::vector<std::vector<int>>& vv …
Run Code Online (Sandbox Code Playgroud) 我刚刚发现这个没有错误编译好(gcc 5.3):
std::vector<whatever> vec;
for( e: vec )
// do something
Run Code Online (Sandbox Code Playgroud)
所有编译器都会发出此警告:
警告:基于范围的for循环没有类型说明符,仅适用于-std = c ++ 1z或-std = gnu ++ 1z
有人能解释一下:
auto
而不是键入它,或者还有更多吗?)我有一些C++代码库,用doxygen记录,并使用GNU make构建.版本信息集中在makefile中,我有类似的东西:
VERSION = 1.2.3.4
在我的makefile中,CFLAGS添加以下定义:
CFLAGS + = -DAPP_VERSION = $(版本)
这使我能够在代码中获取版本,如下所示:
#define STR_EXPAND(tok) #tok
#define STR(tok) STR_EXPAND(tok)
int main()
{
cout << "software version is << STR(APP_VERSION) << endl;
}
Run Code Online (Sandbox Code Playgroud)
现在,我想要的是在doxygen生成的html文件中有这个:
当前版本的软件是1.2.3.4
我设法将makefile变量导出到doxygen配置文件中:( 编辑:从makefile调用doxygen,通过'make-doc'目标)
PREDEFINED = APP_VERSION = $(版本)
但是,如果我尝试使用doxygen\mainpage这样的命令,它会失败,因为(当然),宏名称不会在评论中扩展...
/**
\mainpage this is the doc
Current version is $(APP_VERSION) -- or -- ... is APP_VERSION
*/
Run Code Online (Sandbox Code Playgroud)
问题
你知道在doxygen评论中"扩展"这个宏的方法吗?这可以通过对makefile中保存注释的文件进行一些sed处理来完成,但是这可以直接用doxygen解决吗?
其他项目如何处理版本控制(除了VCS提供的自动版本控制工具,我的意思),以版本ID在文件中唯一定义的方式,因此它可以由软件构建系统和文档构建系统获取.
相关:如何显示定义的值
这段代码是正确的C++:
#include <ctime>
int main()
{
std::time_t t = std::time(nullptr);
}
Run Code Online (Sandbox Code Playgroud)
但是,这也编译得很好(GCC 5.2):
#include <ctime>
int main()
{
time_t t = time(nullptr);
}
Run Code Online (Sandbox Code Playgroud)
更一般地说,传统的"C"数据类型和函数似乎不需要命名空间限定.
在我看来,这是一种危险的行为,因为两者都被接受,名称冲突的可能性仍然存在.我想(错误地?)标准名称空间std
是为了保护我免受此攻击.
所以我的问题是:为什么标准化委员会在C++ 11中允许这样的行为?我的分析错了吗?
我理解遗留代码的问题,但我虽然".h"头文件(iostream.h
,...)专门用于解决这一点.
编辑:链接的问题不是重复的,它询问是否应该使用std::
旧版功能的版本.我想知道的是这种行为背后的基本原理.
我正在使用GLFW,所以用OpenGL设置一个Window.由于我刚刚开始学习OpenGL及其周围的所有内容,这可能听起来像一个愚蠢的问题,但为什么GLFW的示例程序在Window未被主动显示时使用接近100%的CPU(最小化或被另一个窗口隐藏) )?
这是GLFW的例子,我在Mac OS上使用Xcode运行它:
#include <GLFW/glfw3.h>
int main(void)
{
GLFWwindow* window;
if (!glfwInit()) /* Initialize the library */
return -1;
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
/* Render here */
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll …
Run Code Online (Sandbox Code Playgroud)