我正在尝试实现一个在定位器服务后面抽象的日志系统(以本指南的风格),以便日志系统可以针对各种不同的日志记录情况进行子类化。我希望能够使用 printf 样式格式字符串而不是 <<,但这意味着支持可变数量的参数。可变参数模板可以轻松解决这个问题,但是它们不能是虚拟的,这意味着基本日志记录类不能是抽象的(作为接口)。
理想情况下,我需要的是某种方法让父方法不模板化,而只是接受参数包,并将其转发到正确的(模板化的)子方法。我主要看到两种实现此目的的方法,一种是使用 va_list ,它显然不安全、复杂,并且实际上并不意味着可以轻松地与可变参数模板交互;另一种是 CRTP,它可以工作,但意味着不能声明抽象的指针定位器对象中的基类而不知道子类类型,这违背了目的。
下面是假设虚拟模板是一个东西的示例代码:
class Logger
{
public:
template <typename ... Args>
virtual void print(char *filename, int line, std::string &&msg, Args&& ... args) = 0;
protected:
template <typename ... Args>
std::string format(char *filename, int line, std::string &msg, Args&& ... args)
{
std::string output = "%s at line %i: " + msg;
int size = std::snprintf(nullptr, 0, output.c_str());
// +1 for null termination
std::vector<char> buf(size + 1);
std::snprintf(&buf[0], buf.size(), output.c_str(), filename, line, args...);
return …Run Code Online (Sandbox Code Playgroud) 我有一个dict,浮点数作为键,对象作为值.我收到一个浮动,我想知道浮动的两个键之间.我怎么找到这个?
我在代码中的含义示例:
a = {}
a[1.2] = some_unimportant_instance
a[2.3] = some_other_unimportant_instance
a[2.6] = some_third_unimportant_instance
etc...
r = 2.5
# a[r] will not work
# I want something that returns the two numbers around r
# in this case, 2.3 and 2.6.
Run Code Online (Sandbox Code Playgroud) 我的代码创建了一个包含许多顶点的网格,然后在顶点着色器中用高度随机噪声值替换它们.四处走动
glTranslated(-camera.x, -camera.y, -camera.z);
Run Code Online (Sandbox Code Playgroud)
工作正常,但这意味着你可以直到网格的边缘.
我想过将相机位置发送到着色器,并让整个位移被它偏移.因此最终的顶点着色器代码:
uniform vec3 camera_position;
varying vec4 position;
void main()
{
vec3 tmp;
tmp = gl_Vertex.xyz;
tmp -= camera_position;
gl_Vertex.y = snoise(tmp.xz / NOISE_FREQUENCY) * NOISE_SCALING;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
position = gl_Position;
}
Run Code Online (Sandbox Code Playgroud)
编辑:我修复了一个缺陷,顶点本身不应该水平移位.
但是出于某种原因,当我运行它并改变相机位置时,屏幕会闪烁,但没有任何动作.顶点被噪声值正确移位,着色和一切都有效,但位移不会移动.
作为参考,这里是git存储库:https://github.com/Orpheon/Synthworld
我究竟做错了什么?
PS:"闪烁"是错误的.这就好像在某些位置它不会绘制任何东西,而其他位置则从位置0绘制正常场景,因此如果我在不停止的情况下移动它会闪烁.我可以在它保持黑色的地方停留,或者在它保持正常的地方停留.