从C ++ 2a开始,虚拟函数现在可以是constexpr。但是据我所知,您仍然不能在constexpr上下文中调用任意函数指针。
动态多态通常使用vtable来实现,其中包含要调用的函数指针。
另外,动态多态性virtual对于调用您不知道在编译时是哪个类型的重写函数很有用。例如:
struct A {
virtual void fn() const {
std::cout << 'A' << std::endl;
}
};
void a_or_b(A const& a) {
// The compiler has no idea `B` exists
// it must be deferred at runtime
a.fn();
}
struct B : A {
void fn() const override {
std::cout << 'A' << std::endl;
}
};
int main() {
// We choose which class is sent
a_or_b(rand() % 2 ? A{} : B{});
}
Run Code Online (Sandbox Code Playgroud)
因此,考虑到那些在编译时无法调用函数指针并且在编译器没有足够的信息来静态地推断要调用的函数时使用了虚拟多态性的方法,虚拟constexpr函数怎么可能?
我正在尝试在Linux中的程序之间进行双向多对一通信。
我的计划如下:一个与硬件对话的名为“驱动程序”的程序需要与Linux中未知数量的应用程序进行通信。我读到,用于进程间通信的最常见方法之一是“命名管道”。
我还没有发现的问题是:新程序应如何通知驱动程序新程序正在运行,以便在新程序与驱动程序之间建立另一个连接(命名管道)?
所有程序将用C ++编写
请考虑以下内容(它不会编译,但稍后会修复):
void foo(const int *n) { }
template <typename ...Args>
void bar(void (*func)(Args...), Args... args) { func(args...); }
int main(int argc, char *argv[])
{
int n = 42;
bar(foo, &n);
}
Run Code Online (Sandbox Code Playgroud)
模板函数bar()需要一个函数指针来调用,并将参数包传递给它。gcc 7.4.0诊断以下错误:
test.cpp:6:6: note: template argument deduction/substitution failed:
test.cpp:11:16: note: inconsistent parameter pack deduction with ‘const int*’ and ‘int*’
Run Code Online (Sandbox Code Playgroud)
很明显,类型推导规则不够宽松,无法const T*同时观察到const T*和被推导T*。好的。这很容易用演员表修复:
bar(foo, static_cast<const int *>(&n));
Run Code Online (Sandbox Code Playgroud)
但这是丑陋的。C ++ 17具有std::as_const()使它变得不那么丑陋的(&std::as_const(n))的功能,但是在我当前的项目中,我仅限于C ++ 14的sadface。 …
我以以下简单形式提出我的问题:
class animal {
public:
animal() {
_name="animal";
}
virtual void makenoise(){
cout<<_name<<endl;
}
string get_name(){
return _name;
}
protected:
string _name;
};
class cat : public animal {
public:
cat() {
this->_name="cat";
}
};
class dog : public animal {
public:
dog() {
this->_name = "dog";
}
};
Run Code Online (Sandbox Code Playgroud)
我想将所有动物类型一起存储在单个容器中,例如:
vector<animal*> container;
barnyard.push_back(new animal());
barnyard.push_back(new dog());
barnyard.push_back(new cat());
Run Code Online (Sandbox Code Playgroud)
在代码的某个时刻,我需要将dog对象转换为cat对象。我需要进行的转换是设置一个新的dog对象,并用与cat对应的对象相同的索引号替换它。据我了解,dynamic_cast在这种情况下不起作用,并且基于将C ++强制转换为派生类的方法,因此提到这种转换不是一种好习惯。由于模型中的猫和狗具有不同的行为特性,因此我不想将它们的定义放入动物模型中。另一方面,将它们分别存储在不同向量中将很难处理。有什么建议么?
不交换
void f(struct a s)
{
int t;
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++) {
if (s.b[j] > s.b[j + 1]) {
s.c = s.b[j];
s.b[j] = s.b[j + 1];
s.b[j + 1] = s.c;
}
}
}
Run Code Online (Sandbox Code Playgroud)
预计将安排输出,但与输入完全相同
The below class is meant to be a top-layer class which brings all the benefits of nlohman::json but offers additional functions.
#include <nlohmann/json.hpp>
class Other { /* ... */ };
class AbstractData : public nlohmann::json
{
public:
AbstractData (const nlohmann::json& json) : nlohmann::json(json) { }
Other createOther(const char* key) { /* create Other class using key */ }
std::string toString() { /* convert to string */ }
/* etc. */
};
Run Code Online (Sandbox Code Playgroud)
But I ran into issues when using operator[]. …
我想创建一个基于速度的运动的二维游戏。正如当前的代码一样,我正在使用增量时间来使帧率之间的速度变化保持一致。但是,当在144hz监视器上运行时,跳跃时的跳跃高度每次跳跃都略有不同(最大相差约3个像素,最大高度约为104像素),但是当我切换到60hz时,跳跃高度会立即增加平均约5像素,最大高度约109像素。
我曾尝试过用增量时间对哪些值进行规范化的许多不同变体,但我总是回到最接近我想要的输出的那个值。
static bool grounded = false;
if (!grounded) {
velocity.y += (5000.0f * deltaTime); //gravity
}
if (keys[SPACE_INPUT]) { //jump command
if (grounded) {
position.y = 750;
velocity.y = -1000.0f;
grounded = false;
}
}
//Used to measure the max height of the jump
static float maxheight = position.y;
if (position.y < maxheight) {
maxheight = position.y;
std::cout << maxheight << std::endl;
}
//if at the top of the screen
if (position.y + (velocity.y * deltaTime) < 0) { …Run Code Online (Sandbox Code Playgroud) 如果我想更改全局变量,我可以直接在 C++ 中执行:
#include <stdio.h>
int x = 1;
int main()
{
x = 1 + x;
printf("%d\n", x);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但使用 Python 时出现错误:
x = 1
def foo():
x += 1
foo()
Run Code Online (Sandbox Code Playgroud)
UnboundLocalError: local variable 'x' referenced before assignment
我必须添加global x功能foo才能实现它。
似乎 python 让它更明确,是“只是为了明确”的原因吗?
考虑以下代码:
int main()
{
struct EmptyStruct{
void nonstatic_mf() const { std::cout <<"EmptyStruct\n"; }
};
EmptyStruct *esptr = nullptr;
esptr->nonstatic_mf();
}
Run Code Online (Sandbox Code Playgroud)
这是一个合法的 C++(它似乎在 gcc 和 clang 中工作)?
我有一个看起来像这样的代码:
auto func() -> asio::awaitable<void> {
try {
co_await async_operation();
} catch(boost::system::system_error const& e) {
co_return co_await another_async_operation();
}
}
Run Code Online (Sandbox Code Playgroud)
此代码在 GCC 11 中完美运行,但在 GCC 12 中无法编译:
file.cpp:3:19: error: await expressions are not permitted in handlers
3 | co_return co_await another_async_operation();
| ^~~~~~~~
Run Code Online (Sandbox Code Playgroud)
这是为什么?我该如何解决它?
c++ ×10
c++20 ×2
inheritance ×2
c++14 ×1
c++17 ×1
class ×1
const ×1
constexpr ×1
function ×1
game-physics ×1
gcc ×1
gcc12 ×1
global ×1
linux ×1
named-pipes ×1
pointers ×1
polymorphism ×1
python ×1
reference ×1
struct ×1
swap ×1