我已经在C#中成功实现了A*pathfinding,但它很慢,我不明白为什么.我甚至尝试不对openNodes列表进行排序,但它仍然是相同的.
地图是80x80,有10-11个节点.
我从维基百科那里拿了伪代码
这是我的实施:
public static List<PGNode> Pathfind(PGMap mMap, PGNode mStart, PGNode mEnd)
{
mMap.ClearNodes();
mMap.GetTile(mStart.X, mStart.Y).Value = 0;
mMap.GetTile(mEnd.X, mEnd.Y).Value = 0;
List<PGNode> openNodes = new List<PGNode>();
List<PGNode> closedNodes = new List<PGNode>();
List<PGNode> solutionNodes = new List<PGNode>();
mStart.G = 0;
mStart.H = GetManhattanHeuristic(mStart, mEnd);
solutionNodes.Add(mStart);
solutionNodes.Add(mEnd);
openNodes.Add(mStart); // 1) Add the starting square (or node) to the open list.
while (openNodes.Count > 0) // 2) Repeat the following:
{
openNodes.Sort((p1, p2) => p1.F.CompareTo(p2.F));
PGNode current = openNodes[0]; …Run Code Online (Sandbox Code Playgroud) 我想在我的游戏引擎中实现确定性,以便能够保存和重放输入序列并使网络更容易.
我的引擎目前使用一个可变的时间步长:每一帧我计算更新/绘制最后一个时间并将其传递给我的实体的更新方法所花费的时间.这使得1000FPS游戏看起来像30FPS游戏一样快,但引入了不确定行为.
一个解决方案可能是将游戏固定到60FPS,但它会使输入更加延迟,并且不会获得更高帧率的好处.
所以我尝试使用一个线程(不断调用update(1)然后休眠16ms)并在游戏循环中尽可能快地绘制.它有点工作,但它经常崩溃,我的游戏变得无法播放.
有没有办法在我的游戏循环中实现线程来实现确定性而不必重写所有依赖于引擎的游戏?
我正在尝试创建Don Clugston的成员函数指针和最快可能的C++代表的C++ 11实现,并使其成为std::function替代品.
我像这样构造lambda FastDelegates:
// FastFunc is my name for FastDelegate
template<typename LambdaType> FastFunc(LambdaType lambdaExpression)
{
this->m_Closure.bindmemfunc(&lambdaExpression, &LambdaType::operator());
}
Run Code Online (Sandbox Code Playgroud)
现在,一些测试:
FastFunc<void()> test = []{ std::cout << "hello" << std::endl; };
test();
// Correctly prints "hello"
bool b{false};
FastFunc<void()> test2 = [&b]{ std::cout << b << std::endl; };
test2();
// Crash!
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,当lambda是"微不足道的"(没有捕获)时,按值复制并获取其地址是有效的.但是当lambda存储某种状态(捕获)时,我不能只按值将其复制到FastFunc.
我尝试通过引用获取lambda,但是当它像示例中的临时时我不能这样做.
我必须以某种方式将 lambda 存储在其中FastFunc,但我不想使用std::shared_ptr因为它很慢(我尝试了一个使用它的不同fastdelegate实现,并且它的性能可比std::function).
我怎样才能让我实现Don Clugston最快的C++代表与lambdas一起工作,捕获状态,保持fastdelegates的惊人表现?
是.
假设我有一个包含typedef的简单可变结构:
template<typename... TArgs> struct TupleTypeHolder {
using TupleType = std::tuple<TArgs*...>;
};
Run Code Online (Sandbox Code Playgroud)
我想将TupleTypeHolder<something>模板参数传递给另一个类,并获取该typedef.
我的所有尝试都没有编译.
// None of these is valid
template<template<typename...> class TTupleTypeHolder> struct TupleMaker {
using MyTupleType = TTupleTypeHolder::TupleType; // Not valid
using MyTupleType = typename TTupleTypeHolder::TupleType; // Not valid
};
template<template<typename... A> class TTupleTypeHolder> struct TupleMaker2 {
// A is not a valid name here
using MyTupleType = TTupleTypeHolder<A...>::TupleType; // Not valid
using MyTupleType = typename TTupleTypeHolder<A...>::TupleType; // Not valid
};
Run Code Online (Sandbox Code Playgroud)
有没有办法使用可变参数模板类的可变参数模板参数(在本例中为TupleTypeHolders TArgs...)来自使用上述类作为模板可变参数模板参数的类? …
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
enum class En{A, B};
std::vector<En> vec{En::A, En::B, En::A, En::B, En::A, En::B, En::A};
for(const auto& i : vec) std::cout << int(i) << ", ";
std::cout << std::endl;
vec.erase(std::remove(std::begin(vec), std::end(vec), vec.front()),
std::end(vec));
for(const auto& i : vec) std::cout << int(i) << ", ";
std::cout << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Ideone:http://ideone.com/NTPVyE
打印:
0,1,0,1,0,1,0,
1,0,0,0,
为什么会这样?不应该只删除矢量的第一个元素吗?
我想std::remove不会停留在第一个元素,而是贯穿整个向量.有没有什么方法可以使用非独特元素的集合上的擦除删除习惯用法?
我有一个库,它既可以用作仅标头库,也可以用作传统库。为了启用这个可选的仅头.cpp文件功能,如果在仅头文件模式下编译,库将包含源文件。例子:
// Vector.hpp
// (Module file), intended to be included manually by the user
#ifndef LIBRARY_MODULE_VECTOR
#define LIBRARY_MODULE_VECTOR
#include "Library/Vector/Inc/Vector2.hpp"
#include "Library/Vector/Inc/Vector3.hpp"
#include "Library/Vector/Inc/VectorUtils.hpp"
#if defined(LIBRARY_HEADERONLY)
#include "Library/Vector/Src/Vector2.cpp"
#include "Library/Vector/Src/Vector3.cpp"
#include "Library/Vector/Src/VectorUtils.cpp"
#endif
#endif
Run Code Online (Sandbox Code Playgroud)
当用户Vector.hpp在他/她的项目之一中包含时,如果LIBRARY_HEADERONLY定义了,则实现源文件将被包含在头文件之后。小心使用inline关键字以避免多重定义。
如果LIBRARY_HEADERONLY未定义,.cpp则将编译文件并且必须链接库。
我选择的构建系统是CMake。
使用 CMake 标志,用户可以定义或取消定义LIBRARY_HEADERONLY。
该CMakeLists.txt文件类似于:
# (not shown) set flag and cache variables...
# Include library directory
include_directories("./${INCLUDE_DIRECTORY}")
# Glob all library header/source files
file(GLOB_RECURSE SRC_LIST …Run Code Online (Sandbox Code Playgroud) 假设我有一些lambda具有完全相同的捕获和完全相同的签名.
int captured;
auto l0 = [&captured](int x){ captured += x; };
auto l1 = [&captured](int x){ captured -= x; };
auto l2 = [&captured](int x){ captured = x + 1; };
Run Code Online (Sandbox Code Playgroud)
现在,假设我需要将这些lambdas存储在一个std::vector,在运行时调用它们.
我不能使用原始函数指针,因为捕获的变量强制lambda成为仿函数,而不是传统函数.
我可以使用std::function,但它太过分了,因为我确信所有的lambda都有相同的签名和相同的捕获.由于std::function支持具有相同签名但不同捕获的 lambda ,我(很可能)支付额外的运行时成本,可以避免(?).
std::vector<decltype(l0)> v0; // Ok
v0.emplace_back(l0); // Ok
v1.emplace_back(l1); // Nope: `decltype(l0) != decltype(l1)`
v2.emplace_back(l2); // Nope: `decltype(l0) != decltype(l2)`
Run Code Online (Sandbox Code Playgroud)
我想要找到所有lambda之间的共同类型,但std::common_type不起作用.
// Nope: does not compile
using …Run Code Online (Sandbox Code Playgroud) #include <iostream>
using namespace std;
template<typename T> void print(T&& mX)
{
std::cout << std::forward<T>(mX) << std::endl;
}
struct SomeStruct
{
static constexpr const char* someString{"hello!"};
SomeStruct()
{
print(someString);
}
};
int main()
{
SomeStruct s{};
return 0;
}
Run Code Online (Sandbox Code Playgroud)
clang++ -std=c++1y ./code.cpp -o code.o
/tmp/code-a049fe.o:在函数“ SomeStruct :: SomeStruct()”中:./code.cpp:(.text._ZN10SomeStructC2Ev[_ZN10SomeStructC2Ev]+0xa):未定义对“ SomeStruct :: someString”的引用:错误:链接器命令失败,退出代码为1(使用-v查看调用)
g++ -std=c++1y ./code.cpp -o code.o
/tmp/ccyrTsjS.o:在函数“ SomeStruct :: SomeStruct()”中:code.cpp :(。text._ZN10SomeStructC2Ev [_ZN10SomeStructC5Ev] + 0xd):未定义对“ SomeStruct :: someString”的引用collect2:错误:trud退出状态
为什么发生此链接器错误?难道someString在编译时就无法解决吗?
另外,如果print(someString)将其替换为错误,则不会发生cout << someString;
我无数次编写了在访问其内存或外部内存后生成分段错误的代码:std::vectorstd::string
std::string test{"hello!"};
std::cout << test[12] << std::endl;
Run Code Online (Sandbox Code Playgroud)
这是一个可以在非优化/调试构建中在运行时捕获的错误,只需简单断言的少量额外成本。(但由于我们正在构建没有-DNDEBUG和没有-O3我们不期望获得最大性能。)
有什么理由std::string::operator[]不这样实施吗?
标准是否禁止在库代码中使用断言?
char std::string::operator[](std::size_t i)
{
// `assert_with_message` only exists in debug mode
#ifndef NDEBUG
assert_with_message(i < this->size(),
"Tried to access character " + std::to_string(i)
+ " from string '" + *this + "' of size "
+ std::to_string(this->size()));
#endif
return data[i];
}
Run Code Online (Sandbox Code Playgroud)
-DNDEBUG在没有编译程序的情况下编译程序并在运行时看到类似此消息的内容将非常有帮助:
断言已触发:尝试从字符串“hello!”访问字符 12 尺寸为 6。
按 (0) 继续。
按 (1) 中止。
请注意,术语“断言”指的是开发/调试构建检查,应从发布/优化构建中完全删除/优化该检查。
我正在尝试编写一个Bind元编程模板辅助元函数,它将模板参数绑定到某个东西上.
我有一个简单模板元函数的工作实现:
template<typename T0, typename T1>
struct MakePair
{
using type = std::pair<T0, T1>;
};
template<template<typename...> class TF, typename... Ts>
struct Bind
{
template<typename... TArgs>
using type = TF<Ts..., TArgs...>;
};
using PairWithInt = typename Bind<MakePair, int>::type;
static_assert(std::is_same<PairWithInt<float>, MakePair<int, float>>{}, "");
Run Code Online (Sandbox Code Playgroud)
但是,如果MakePair模板参数是模板模板呢?还是简单的数值?
template<template<typename> class T0, template<typename> class T1>
struct MakePair0
{
using type = /*...*/;
};
template<template<typename...> class TF, template<typename> class... Ts>
struct Bind0 { /*...*/ }
// ...
template<int T0, int T1>
struct MakePair1
{ …Run Code Online (Sandbox Code Playgroud) c++ ×9
c++11 ×4
c++14 ×3
lambda ×2
templates ×2
.net ×1
a-star ×1
assert ×1
c# ×1
cmake ×1
constexpr ×1
delegates ×1
game-engine ×1
header-files ×1
header-only ×1
libstdc++ ×1
linker ×1
makefile ×1
optimization ×1
path-finding ×1
std ×1
std-function ×1
types ×1