小编GMa*_*ckG的帖子

使用Lua时在C++中进行堆栈展开

我最近偶然发现了这个C++/Lua错误

int function_for_lua( lua_State* L )
{
   std::string s("Trouble coming!");
   /* ... */
   return luaL_error(L,"something went wrong");
}
Run Code Online (Sandbox Code Playgroud)

错误是luaL_error使用longjmp,因此堆栈永远不会解开并且s永远不会被破坏,泄漏内存.还有一些Lua API无法解开堆栈.

一个显而易见的解决方案是在C++模式下编译Lua,但有例外.然而,我不能像Luabind那样需要标准的C ABI.

我目前的想法是编写我自己的函数,模仿Lua API的麻烦部分:

// just a heads up this is valid c++.  It's called a function try/catch.
int function_for_lua( lua_State* L )
try
{
   /* code that may throw Lua_error */
}
catch( Lua_error& e )
{
   luaL_error(L,e.what());
}
Run Code Online (Sandbox Code Playgroud)

所以我的问题是:function_for_lua堆栈是否正确解开.可能会出错吗?

c++ lua destructor stack-unwinding

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

如何查找参数包的长度?

假设我有一个可变参数模板函数

template<typename... Args>
unsigned length(Args... args);
Run Code Online (Sandbox Code Playgroud)

如何使用长度函数找到参数列表的长度?

c++ templates variadic variadic-functions c++11

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

包含警卫的问题

当我为我的头文件添加一个包含Guard的Visual C++项目时,它给了我以下警告和错误:

警告C4603:'_ MAPTEST_H':未定义宏或预编译头使用后定义不同

将宏添加到预编译头,而不是在此处定义

.\ MapTest.cpp(6):使用预编译头**//预编译头stdafx.h包含在此行中

.\ MapTest.cpp(186):致命错误C1020:意外#endif

但是当我在include guard之前添加预编译头时,不会发出警告或错误.这是什么原因?

c++ visual-c++ inclusion

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

VC++是否支持_mm_malloc?

Visual Studio C++ 2008/2010是否_mm_malloc正式支持?它已定义,malloc.h但我无法在MSDN库中找到它的描述.

c++ memory-management memory-alignment visual-c++

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

转换为基类有效性

假设我有一个名为的类Base和一个派生自它的类SuperBase.鉴于add接受a Base*,其中任何一个都是有效的:

SuperBase *super = new SuperBase;
bases.add(super);
Run Code Online (Sandbox Code Playgroud)

要么

SuperBase *super = new SuperBase;
bases.add((Base*)super);
Run Code Online (Sandbox Code Playgroud)

c++ polymorphism casting

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

指针向量的迭代器没有正确解除引用

这是我的问题:

我有一个std::vector<AguiWidgetBase*>用于跟踪儿童控制的东西.

我有这两个函数来返回迭代器:

std::vector<AguiWidgetBase*>::const_iterator AguiWidgetBase::getChildBeginIterator() const
{
    return children.begin();
}

std::vector<AguiWidgetBase*>::const_iterator AguiWidgetBase::getChildEndIterator() const
{
    return children.end();
}
Run Code Online (Sandbox Code Playgroud)

然后我像这样使用它:

for(std::vector<AguiWidgetBase*>::const_iterator it = box->getChildBeginIterator(); 
    it != box->getChildEndIterator(); ++it)
{
    it->setText("Hello World");
}
Run Code Online (Sandbox Code Playgroud)

我收到这些错误:

Error   3   error C2039: 'setText' : is not a member of 'std::_Vector_const_iterator<_Ty,_Alloc>'   c:\users\josh\documents\visual studio 2008\projects\agui\alleg_5\main.cpp   112
Error   2   error C2839: invalid return type 'AguiWidgetBase *const *' for overloaded 'operator ->' c:\users\josh\documents\visual studio 2008\projects\agui\alleg_5\main.cpp   112
Run Code Online (Sandbox Code Playgroud)

为什么它会给我这些错误?

谢谢

c++ iterator vector

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

如何使用Boost :: Spirit :: Lex来调用文件而不先将整个文件读入内存?

我正在寻找使用boost :: spirit :: lex编写词法分析器,但我能找到的所有示例似乎都假设您已将整个文件首先读入RAM.我想写一个不需要整个字符串在RAM中的词法分析器,这可能吗?或者我需要使用其他东西吗?

我尝试使用istream_iterator,但是boost会给我一个编译错误,除非我使用const char*作为迭代器类型.

例如,我能找到的所有例子基本上都是这样做的:

lex_functor_type< lex::lexertl::lexer<> > lex_functor;

// assumes entire file is in memory
char const* first = str.c_str();
char const* last = &first[str.size()];

bool r = lex::tokenize(first, last, lex_functor, 
    boost::bind(lex_callback_functor(), _1, ... ));
Run Code Online (Sandbox Code Playgroud)

另外,是否有可能以某种方式确定lex令牌的行/列号?

谢谢!

c++ boost lex boost-spirit

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

Rvalue参考参数和模板函数

如果我定义一个接受rvalue引用参数的函数:

template <typename T>
void fooT(T &&x) {}
Run Code Online (Sandbox Code Playgroud)

我可以调用它,使用GCC 4.5,无论使用哪种a,ar或者arr:

int a, &ar = a, &&arr = 7;
fooT(a); fooT(ar); fooT(arr);
Run Code Online (Sandbox Code Playgroud)

但是,调用类似的非模板函数,

void fooInt(int &&x) {}
Run Code Online (Sandbox Code Playgroud)

这三个参数中的任何一个都会失败.我正准备加强我的知识forward,但这已经让我失去了理智.也许它是GCC 4.5; 我很惊讶地发现Rvalue References简介中的第一个例子也给出了一个编译错误:

A a;
A&& a_ref2 = a;  // an rvalue reference
Run Code Online (Sandbox Code Playgroud)

c++ rvalue-reference c++11

6
推荐指数
2
解决办法
3125
查看次数

std :: transform和move语义

我正在使用Boost.Filesystem来创建目录中的文件列表.我使用boost::filesystem::recursive_directory_iterator,并std::copy把每个路径到一个std ::向量作为一个boost::filesystem::directory_entry对象.我希望以std :: strings的形式输出到文件,所以我做了以下(\n以避免使用<<):

std::vector<boost::filesystem::directory_entry> buffer; //filled with paths
...
std::vector<std::string> buffer_native(buffer.size());
//transform directory_entry into std::string, and add a \n, so output is formatted without use of <<
std::transform(buffer.begin(),buffer.end(),buffer_native.begin(), [](boost::filesystem::directory_entry de)->std::string
    {
        std::string temp=de.path().string();
        temp+="\n";
        return temp;
    }
    buffer.clear();
    std::copy(buffer_native.begin(),buffer_native.end(),std::ostream_iterator<std::string>(out_file));
Run Code Online (Sandbox Code Playgroud)

然而,这个问题是它创建了两个向量,其原始立即被清除,因为它不需要.这听起来像移动语义的完美位置,但是n3242只提供与C++ 98相同的两个转换重载.是否有可能实现移动语义std::transform?如果不是,那么编写自定义循环会更好吗?

我在Windows XP上使用GCC 4.5.2(MinGW).

c++ stl c++11

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

__faststorefence的行为是什么?

关于这个问题,我只对x86和x86-64感兴趣.

对于MSVC 2005,__ faststorefence的文档说:"保证每个先前的商店在任何后续商店之前全局可见."

对于MSVC 2008和2010,它改为:"保证每个先前的内存引用,包括加载和存储内存引用,在任何后续内存引用之前全局可见."

写入后者的方式,我认为这也会阻止CPU在旧商店之前重新排序负载.这与第一个定义不同,后者暗示内在函数仅用于处理使用旧存储的非临时存储的阻塞或重新排序(唯一的其他重新排序x86(-64)确实如此).

然而,文档似乎与自己相矛盾:"在x64平台上,此例程生成的指令比sfence指令更快的存储范围.在x64平台上使用此内在而不是_mm_sfence."

这意味着它仍然具有类似sfence的功能,因此仍然可以使用较旧的存储重新排序负载.那是哪个呢?有人能解决我的困惑吗?

PS:寻找这个函数的GCC版本,我遇到了long local; __asm__ __volatile__("lock; orl $0, %0;" : : "m"(local));但我觉得它来自32位代码; 什么是64位模拟?

multithreading memory-fences visual-c++ memory-barriers

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