假设有一个库,其中一个版本定义了一个带名称的函数foo,另一个版本的名称已更改为foo_other,但这两个函数仍具有相同的参数和返回值.我目前使用这样的条件编译:
#include <foo.h>
#ifdef USE_NEW_FOO
#define trueFoo foo_other
#else
#define trueFoo foo
#endif
Run Code Online (Sandbox Code Playgroud)
但这需要对库版本进行一些外部检测并设置相应的编译器选项-DUSE_NEW_FOO.我宁愿让代码自动确定它应该调用什么函数,基于它被声明或不被声明<foo.h>.
有没有办法在任何版本的C中实现这一点?
如果没有,切换到任何版本的C++会为我提供任何方法吗?(假设库执行所有需要的操作,如extern "C"标题中的块)?也就是说,我正在考虑以某种方式利用SFINAE,但是对于全局函数而不是方法,这是在链接问题中讨论的.
考虑以下代码(使用Eigen):
#include <Eigen/Dense>
#include <iostream>
template<int rows, int cols, int row, class R, class Rv, int N, class... Rs>
inline typename std::enable_if<sizeof...(Rs)==0>::type
setRow(Eigen::Matrix<R,rows,cols>&)
{}
template<int rows, int cols, int row, class R, class Rv, int N=0, class... Rs>
inline typename std::enable_if<sizeof...(Rs)==cols-N-1>::type
setRow(Eigen::Matrix<R,rows,cols>& m, Rv val, Rs...args)
{
m(row,N)=val;
setRow<rows,cols,row,R,Rv,N+1>(m,args...);
}
template<class T, int R, int C, int CUR_ROW>
class MatrixConstructor
{
Eigen::Matrix<T,R,C> m;
public:
MatrixConstructor(const Eigen::Matrix<T,R,C>& m)
: m(m)
{}
MatrixConstructor()
{}
template<class...Ts>
typename std::enable_if<sizeof...(Ts)==C && CUR_ROW<R-1,
MatrixConstructor<T,R,C,CUR_ROW+1>>::type …Run Code Online (Sandbox Code Playgroud) 由于以下代码无法编译 error: redefinition of ‘template<class Integer, class> void func(Integer)’
#include <iostream>
#include <type_traits>
template<typename Float, typename = typename
std::enable_if<std::is_floating_point<Float>::value>::type>
void func(Float floatVal)
{
std::cerr << "float: " << floatVal << "\n";
}
template<typename Integer, typename = typename
std::enable_if<std::is_integral<Integer>::value>::type>
void func(Integer integer)
{
std::cerr << "integral: " << integer << "\n";
}
int main()
{
func(32.4246);
func(144532);
}
Run Code Online (Sandbox Code Playgroud)
但是这两个函数在模板实例化上显然会有不同的签名.那为什么不能编译呢?
请注意:我确实知道如何解决这个问题:只需在其中一个函数中添加另一个虚拟模板参数,例如typename=void,就可以了,就像这里一样
template<typename Integer, typename dummy=void, typename = typename
std::enable_if<std::is_integral<Integer>::value>::type>
void func(Integer integer){}
Run Code Online (Sandbox Code Playgroud)
但问题是为什么我必须这样做?
一个什么都不做的虚拟析构函数
virtual ~ClassName() {}
Run Code Online (Sandbox Code Playgroud)
从C++ 11开始,我们可以说:
virtual ~ClassName() = default;
Run Code Online (Sandbox Code Playgroud)
这两者有什么区别吗?
我正在尝试改进Henry Thasler的双-单算法的GLSL实现(来自他的GLSL Mandelbrot演示),以在Linux上的NVIDIA图形上可靠地工作。我最近了解到,自OpenGL的4.0(§4.7的精确预选赛中的规范)或GL_ARB_gpu_shader5延长(规格),我们可以使用precise限定词,使计算遵循GLSL源指定的算术运算的精确序列。
但是以下尝试似乎并没有任何改善:
#version 330
#extension GL_ARB_gpu_shader5 : require
vec2 ds_add(vec2 dsa, vec2 dsb)
{
precise float t1 = dsa.x + dsb.x;
precise float e = t1 - dsa.x;
precise float t2 = ((dsb.x - e) + (dsa.x - (t1 - e))) + dsa.y + dsb.y;
precise vec2 dsc;
dsc.x = t1 + t2;
dsc.y = t2 - (dsc.x - t1);
return dsc;
}
Run Code Online (Sandbox Code Playgroud)
结果与未precise添加的结果相同。我检查了算法本身是否正确:它可以precise在Intel …
我正在尝试通过AMD 286系统上的异常处理来初始化保护模式。我已经在Bochs上调试了以下代码,并且在这里可以正常工作。在奔腾4机器上运行时也是如此。但是在286上,当到达int3指令时,它只是三重故障。可以观察到的行为是:如果我注释掉了int3,则会无限期地在屏幕上显示“ OK”,而按原样使用代码,则系统将重新启动。
该代码将由FASM编译,并将二进制文件放入HDD或FDD的引导扇区中。我实际上是从1.4M软盘运行它。
org 0x7c00
use16
CODE_SELECTOR = code_descr - gdt
DATA_SELECTOR = data_descr - gdt
; print "OK" on the screen to see that we've actually started
push 0xb800
pop es
xor di,di
mov ax, 0x0700+'O'
stosw
mov ax, 0x0700+'K'
stosw
; clear the rest of the screen
mov cx, 80*25*2-2
mov ax, 0x0720
rep stosw
lgdt [cs:gdtr]
cli
smsw ax
or al, 1
lmsw ax
jmp CODE_SELECTOR:enterPM
enterPM:
lidt [idtr]
mov cx, DATA_SELECTOR …Run Code Online (Sandbox Code Playgroud) 根据System V X86-64 ABI,应用程序中的函数调用使用以下寄存器序列来传递整数参数:
rdi, rsi, rdx, rcx, r8, r9
Run Code Online (Sandbox Code Playgroud)
但是系统调用参数(除了系统调用号)在另一个寄存器序列中传递:
rdi, rsi, rdx, r10, r8, r9
Run Code Online (Sandbox Code Playgroud)
为什么内核使用r10而不是rcx第四个参数?它是否以某种方式与rcx未被保留的事实有关r10?
我正在尝试使用 GCC,试图说服它假设代码的某些部分无法访问,以便趁机进行优化。我的一项实验给了我一些奇怪的代码。这是来源:
#include <iostream>
#define UNREACHABLE {char* null=0; *null=0; return {};}
double test(double x)
{
if(x==-1) return -1;
else if(x==1) return 1;
UNREACHABLE;
}
int main()
{
std::cout << "Enter a number. Only +/- 1 is supported, otherwise I dunno what'll happen: ";
double x;
std::cin >> x;
std::cout << "Here's what I got: " << test(x) << "\n";
}
Run Code Online (Sandbox Code Playgroud)
我是这样编译的:
g++ -std=c++11 test.cpp -O3 -march=native -S -masm=intel -Wall -Wextra
Run Code Online (Sandbox Code Playgroud)
函数的代码test如下所示:
_Z4testd:
.LFB1397:
.cfi_startproc
fld QWORD PTR [esp+4] …Run Code Online (Sandbox Code Playgroud) 考虑以下代码:
#include <iostream>
bool preInit()
{
std::cerr << "Doing preinitialization...\n";
return true;
}
const bool preinitialized=preInit();
int main()
{
std::cerr << "In main()\nPreinitialization has "
<< (preinitialized ? "" : "not ") << "been done\n";
}
Run Code Online (Sandbox Code Playgroud)
在这里使用std::cerr(以及标准C ++库的任何其他功能)安全preInit()吗?main()根据C ++标准,是否可以保证库在调用之前就可以使用?
目前,我的函数转换结果eglGetError()如下:
std::string eglErrorString(EGLint error)
{
switch(error)
{
case EGL_SUCCESS: return "No error";
case EGL_NOT_INITIALIZED: return "EGL not initialized or failed to initialize";
case EGL_BAD_ACCESS: return "Resource inaccessible";
case EGL_BAD_ALLOC: return "Cannot allocate resources";
case EGL_BAD_ATTRIBUTE: return "Unrecognized attribute or attribute value";
case EGL_BAD_CONTEXT: return "Invalid EGL context";
case EGL_BAD_CONFIG: return "Invalid EGL frame buffer configuration";
case EGL_BAD_CURRENT_SURFACE: return "Current surface is no longer valid";
case EGL_BAD_DISPLAY: return "Invalid EGL display";
case EGL_BAD_SURFACE: return "Invalid surface";
case EGL_BAD_MATCH: return …Run Code Online (Sandbox Code Playgroud)