小编Tob*_*ias的帖子

面向数据访问多个索引数据阵列

我正在为游戏引擎开发实体组件系统.我的目标之一是使用面向数据的方法来实现最佳数据处理.换句话说,我想遵循指导而不是希望结构的结构而不是结构数组.但是,我的问题是我还没有想出一个巧妙的方法来解决这个问题.

到目前为止,我的想法是系统中的每个组件都负责游戏逻辑的特定部分,比如重力组件根据质量,速度等来处理每帧的计算力,而其他组件则负责其他组件.因此,每个组件都对不同的数据集感兴趣.重力组件可能对质量和速度感兴趣,而碰撞组件可能对边界框和位置等感兴趣.

到目前为止,我想我可以拥有一个数据管理器,每个属性保存一个数组.因此,假设实体可能具有权重,位置,速度等中的一个或多个,并且它们将具有唯一ID.数据管理器中的数据将表示如下,其中每个数字代表一个实体ID:

weightarray ->   [0,1,2,3]
positionarray -> [0,1,2,3]
velocityarray -> [0,1,2,3]
Run Code Online (Sandbox Code Playgroud)

如果所有实体都具有每个属性,则此方法很有效.但是,如果只有实体0和2具有所有树属性,而其他属性是不移动类型的实体,则它们将没有速度并且数据看起来如下:

weightarray ->   [0,1,2,3]
positionarray -> [0,1,2,3]
velocityarray -> [0,2]     //either squash it like this
velocityarray -> [0  ,2  ]     //or leave "empty gaps" to keep alignment
Run Code Online (Sandbox Code Playgroud)

突然间,迭代它并不容易.如果我采用第二种方法,那么只对迭代和操纵速度感兴趣的组件必须以某种方式跳过空隙.保持阵列短路的第一种方法在更复杂的情况下也不能很好地工作.假设我有一个具有所有三个属性的实体0,另一个实体1仅具有权重和位置,以及实体2仅具有位置和速度.最后,最后一个实体3只有重量.压扁的阵列看起来像:

weightarray ->   [0,1,3]
positionarray -> [0,1,2]
velocityarray -> [0,2]
Run Code Online (Sandbox Code Playgroud)

另一种方法会留下这样的空白:

weightarray ->   [0,1, ,3]
positionarray -> [0,1,2, ]
velocityarray -> [0, ,2, ]
Run Code Online (Sandbox Code Playgroud)

如果您只想迭代仅具有一些属性的实体集,则这两种情况都是重要的迭代.例如,给定的组件X将对处理具有位置和速度的实体感兴趣.如何提取可迭代的数组指针以使该组件进行计算?我想给它一个数组,其中元素彼此相邻,但这似乎是不可能的.

我一直在考虑解决方案,例如为每个阵列设置一个位字段,描述哪些点有效以及哪些是间隙,或者是将数据复制到没有空洞然后被提供给组件的临时阵列的系统,以及其他想法但没有我想到的是优雅的并且没有额外的处理开销(例如额外检查数据是否有效,或额外的数据复制).

我在这里问,因为我希望你们中的某个人可能有类似的经历,或者可能有想法或想法有助于解决这个问题.:)此外,如果这整个想法是垃圾,不可能正确,你有一个更好的想法,请告诉我.希望这个问题不会太长或太杂乱.

谢谢.

c++ data-oriented-design

14
推荐指数
4
解决办法
2598
查看次数

如何确定某个类型是否具有任何返回类型的成员函数?

我需要找出一个给定类型是否具有函数X作为具有给定参数列表的可调用函数.请在支票上关心的返回值.然而.

我从另一个Stack Overflow问题中找到了这个解决方案似乎运行良好.它的作用是:

#include <type_traits>

template <typename C, typename F, typename = void>
struct is_call_possible : public std::false_type {};

template <typename C, typename R, typename... A>
struct is_call_possible<C, R(A...),
    typename std::enable_if<
        std::is_same<R, void>::value ||
        std::is_convertible<decltype(
            std::declval<C>().operator()(std::declval<A>()...)
        ), R>::value
    >::type
> : public std::true_type {};
Run Code Online (Sandbox Code Playgroud)

这正是我想要的,除了在检查中你还提供了所需的返回类型.我试图找到一种方法来修改它,以便能够检查而不考虑返回类型,但我想不出办法.

有谁知道如何做到这一点?

c++ templates type-traits c++11

12
推荐指数
1
解决办法
603
查看次数

正如Clang似乎指出的那样,这段代码是否真的未定义?

我打开了-fsanitize=undefined使用Catch(单元测试库)的项目.来自Catch的一行被发信号通知此标志导致未定义的行为.我设法做了一个孤立的例子:

#include <iomanip>
#include <sstream>

int main()
{
    std::ostringstream os; 
    os << "0x" << std::setfill('0') << std::hex;
}
Run Code Online (Sandbox Code Playgroud)

编译:

clang++ -fsanitize=undefined main.cpp
Run Code Online (Sandbox Code Playgroud)

如果我运行它,将给出以下打印:

/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/bits/ios_base.h:96:24: runtime error: load of value 4294967221, which is not a valid value for type 'std::_Ios_Fmtflags'
/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../include/c++/4.9.2/bits/ios_base.h:76:67: runtime error: load of value 4294967221, which is not a valid value for type 'std::_Ios_Fmtflags'
Run Code Online (Sandbox Code Playgroud)

这对我来说是clang 3.6.0和一个有clang的朋友3.4-1ubuntu3.在gcc版本上我不会发生这种情况4.9.2

那么这里有什么?这段代码真的很糟糕,还是clang的结尾有什么可疑的?

c++ clang sanitizer libstdc++ undefined-behavior

12
推荐指数
1
解决办法
688
查看次数

如何以允许传递临时值的方式将std :: istream传递给函数?

我试图创建一个构造函数来从任何给它的istream加载资源.我似乎无法找出将istream参数传递给构造函数的最佳方法.

Loader::Loader(istream stream);
Run Code Online (Sandbox Code Playgroud)

由于对象切片,这个很糟糕,所以没有选择.

Loader::Loader(istream& stream);
Run Code Online (Sandbox Code Playgroud)

这就是我现在使用的,看起来还不错.它有一个重要的问题 - 你不能给它一个临时的,因为temporaries不能绑定到非const引用!例如,以下内容不起作用:

Container():
  mLoader(ifstream("path/file.txt", ios::binary)
{
}
Run Code Online (Sandbox Code Playgroud)

这是一个限制,因为我现在被迫将ifstream存储为Container的成员变量,以延长其生命周期.

既然问题出现在非const引用中,那么就可以这样:

Loader::Loader(const istream& stream);
Run Code Online (Sandbox Code Playgroud)

但是因为.seek()等是非const的,所以这也不是一个选择......

那么,如何以一种简洁的方式解决这个问题呢?

c++ istream

6
推荐指数
1
解决办法
645
查看次数

Constexpr替代放置new以便能够将对象保留在内存中未初始化?

我正在尝试创建一个静态容器,它具有基于堆栈的内存并且可以容纳N个实例.很多相似std::vector我希望当前未使用的内存不包含T的初始化项目.这通常通过新的放置来解决但是不可能在constexpr.

使用工会 我发现了一个技巧,你可以使用一个联合如下:

template <typename value_type>
union container_storage_type
{
    struct empty{};
    constexpr container_storage_type(): uninitialized{}{}
    constexpr container_storage_type(value_type v): value(v){}
    constexpr void set(value_type v)
    {
        *this = literal_container_storage_type{v};
    }

    empty uninitialized;
    value_type value;
};
Run Code Online (Sandbox Code Playgroud)

这使您可以通过设置empty成员来存储未初始化的项目,这可以解决constexpr中所有成员必须初始化的限制.

现在这种方法的问题在于,如果value_type是实现的类型,工会operator=规则说:

如果一个union包含一个带有非平凡特殊成员函数的非静态数据成员(复制/移动构造函数,复制/移动赋值或析构函数),那么该函数在联合中默认被删除,需要由程序员.

这意味着为了能够使用这个技巧,我需要operator=在工会中实现,但是看起来怎么样?

constexpr container_storage_type& operator=(const container_storage_type& other)
{           
    value = other.value; //ATTEMPT #1
    //*this = container_storage_type(other.value);ATTEMPT #2

    return *this;
}
Run Code Online (Sandbox Code Playgroud)

尝试#1:这似乎不可能,因为编译器抱怨在常量表达式中根本不允许更改union的活动成员.尝试#2:这适用于set()前一个代码段的方法,因为它不会更改活动成员本身,但会重新分配整个联合.这个技巧似乎无法在赋值运算符中使用,因为这会导致无休止的递归...

我在这里遗漏了什么,或者在constexpr中使用工会作为一种新的替代方案,这真的是一个死胡同吗?

还有其他替代方案,我完全错过了新的位置吗?

https://godbolt.org/z/km0nTY说明问题的代码

c++ c++17

6
推荐指数
1
解决办法
378
查看次数

在 Go 中使用 http.FileServer 禁用目录列表的好方法

如果你在 Go 中使用 http.FileServer 像:

func main() {
    port := flag.String("p", "8100", "port to serve on")
    directory := flag.String("d", ".", "the directory of static file to host")
    flag.Parse()

    http.Handle("/", http.FileServer(http.Dir(*directory)))

    log.Printf("Serving %s on HTTP port: %s\n", *directory, *port)
    log.Fatal(http.ListenAndServe(":"+*port, nil))
}
Run Code Online (Sandbox Code Playgroud)

然后访问一个目录会给你一个文件列表。通常这对于 Web 服务是禁用的,而是以 404 响应,我也希望这种行为。

http.FileServer 没有此 AFAIK 的选项,我在这里看到了解决此问题的建议方法https://groups.google.com/forum/#!topic/golang-nuts/bStLPdIVM6w他们所做的是包装 http.FileSystem键入并实现自己的 Open 方法。但是,当路径是目录时,这不会给出 404,它只会给出一个空白页面,并且不清楚如何修改它以适应这一点。这就是他们所做的:

type justFilesFilesystem struct {
    fs http.FileSystem
}

func (fs justFilesFilesystem) Open(name string) (http.File, error) {
    f, err := fs.fs.Open(name)
    if err != nil { …
Run Code Online (Sandbox Code Playgroud)

http fileserver go

5
推荐指数
1
解决办法
2266
查看次数

由于errno,Django 1.8应用程序因初始迁移而神秘失败:150"外键约束不正确"

我正在使用python 3.4在django 1.8中编写应用程序,我遇到了使用MySQL作为数据库后端的问题,这让我完全陷入困境.

当我开始使用新数据库并调用./manage.py migrate(或syncdb)并尝试创建初始数据库时,我得到以下回溯:

(virtualenv)~/projects/projmoj (master ?)?? ? ./manage.py migrate
Operations to perform:
  Synchronize unmigrated apps: allauth, rest_framework, registration, rest_auth, projmoj, messages, project, staticfiles
  Apply all migrations: contenttypes, sites, sessions, task, auth, admin, authtoken, static_precompiler, account
Synchronizing apps without migrations:
  Creating tables...
    Creating table project_project
    Creating table project_membership
    Running deferred SQL...
Traceback (most recent call last):
  File "/home/tobbe/projects/projmoj/virtualenv/lib/python3.4/site-packages/django/db/backends/utils.py", line 62, in execute
    return self.cursor.execute(sql)
  File "/home/tobbe/projects/projmoj/virtualenv/lib/python3.4/site-packages/django/db/backends/mysql/base.py", line 124, in execute
    return self.cursor.execute(query, args)
  File "/home/tobbe/projects/projmoj/virtualenv/lib/python3.4/site-packages/MySQLdb/cursors.py", line 220, in execute …
Run Code Online (Sandbox Code Playgroud)

python mysql django

3
推荐指数
1
解决办法
2243
查看次数

如何正确解决const std :: string&和const std :: vector <string>&ambiguity?

我有一个函数,我有一个像这样的重载:

void process(const std::string& text)
{
}

void process(const std::vector<std::string>& manyTexts)
{
}
Run Code Online (Sandbox Code Playgroud)

我称之为:

process({"hello", "hey"});
Run Code Online (Sandbox Code Playgroud)

我希望这可以解决第二次重载,但这显然是模棱两可的.令我惊讶的是我发现这个要编译:

std::string text = {"hello", "hey"};
Run Code Online (Sandbox Code Playgroud)

变量只包含'hello',这似乎不是很有用也不直观.

有了这个,我有两个问题:

  1. 是什么导致这是一个有效的初始化std::string
  2. 这可以通过某种方式解决,不涉及重命名功能或避免初始化列表?

c++ overloading c++11

1
推荐指数
1
解决办法
215
查看次数