最近在CodeReview.SE上,我遇到了一个回答,谈到了一种叫做"异常呕吐"的技术.显然,这个技巧用于利用必须以线程安全的方式实现异常,而不管编译器是否支持thread_local变量.
我粘贴以下答案的一部分:
现有的技术并不相同,称为"异常呕吐".注意:
Run Code Online (Sandbox Code Playgroud)void f(void(*p)()) { p(); } template<typename F> void real_f(F func) { try { throw func; } catch(...) { f([] { try { throw; } catch(F func) { func(); } }); } }这滥用了这样的事实:编译器必须为复杂对象提供线程局部堆栈以用作异常存储,而不管它们是否支持其他线程本地特性,因此可以获得广泛的编译器支持.最明显的缺点是a)它太可怕了,b)它仅限于堆栈语义.
我的问题是,这个技巧实际上是如何运作的,它是"安全的"吗?
我写了一个类multi_array,它是std::array多维度的扩展.
template <typename T, std::size_t... N>
class multi_array {
template <std::size_t... I, typename... Idx>
constexpr std::size_t linearized_index(meta::index_sequence<I...>,
Idx... idx) const {
std::size_t index = 0;
using unpack = std::size_t[];
(void)unpack{0UL,
((void)(index = (index + unpack{std::size_t(idx)...}[I]) *
meta::pack_element<I + 1, N...>::value),
0UL)...};
return index + unpack{std::size_t(idx)...}[sizeof...(idx) - 1];
}
// Storage
T m_data[meta::product<N...>::value];
//...
};
Run Code Online (Sandbox Code Playgroud)
我设法获得constexpr元素访问权限,但仅限于C++ 14.问题是功能linearized_index.它在编译时计算线性化索引.为了做到这一点,它以某种方式减少了索引的元组和维度的元组.对于这种减少,我需要在函数内部使用局部变量,但在C++ 11中不允许这样做.我的环境不允许使用C++ 14.我可以以某种方式重写此函数以使用C++ 11吗?
我已经准备了一个完整的(不是那么简单的)用C++编写的例子14.
#include <cstddef> // std::size_t
namespace meta {
// product
template <std::size_t...>
struct …Run Code Online (Sandbox Code Playgroud) c++ templates template-meta-programming variadic-templates c++11
假设我有一个类型T,我想检测它是否有一个下标操作符,我可以用另一种类型调用它Index.以下示例工作得很好:
#include <type_traits>
#include <vector>
template < typename T, typename Index >
using subscript_t = decltype(std::declval<T>()[std::declval<Index>()]);
int main()
{
using a = subscript_t< std::vector<int>, size_t >;
using b = subscript_t< std::vector<int>, int >;
}
Run Code Online (Sandbox Code Playgroud)
但是,当且仅当函数签名完全匹配时,我希望检测函数.在上面的例子中,我希望语句subscript_t< std::vector<int>, int >;抛出一个错误no viable overloaded operator[],因为下标运算符的签名std::vector是
std::vector<T, std::allocator<T>>::operator[](size_type pos);
Run Code Online (Sandbox Code Playgroud)
size_typeGCC 在哪里unsigned long.如何避免隐式转换从int到size_t要发生?
免责声明: 请勿在此问题中使用该代码.它调用未定义的行为.问题的核心陈述,编译器是否为每个lambda生成一个新类型,以及相应的答案仍然有效.
要获取一个带有捕获的lambda的函数指针,我想出了以下技巧:
auto f = [&a] (double x) { return a*x; };
static auto proxy = f;
double(*ptr)(double) = [] (double x) { return proxy(x); };
// do something with ptr
Run Code Online (Sandbox Code Playgroud)
我将lambda与一个捕获(可能是一个函数参数)分配给函数内部的静态变量,所以我不必在另一个lambda中使用它时捕获它.然后另一个无捕获的lambda可以快乐地衰减到一个函数指针,我可以传递给一些共享库.
现在可以尝试概括一下:
template < typename F >
decltype(auto) get_ptr(F f)
{
static auto proxy = f;
return [] (auto ... args) { return proxy(args...); };
}
Run Code Online (Sandbox Code Playgroud)
但是,作为proxy静态变量,它将在每次调用函数时被覆盖.因为它是一个模板,我认为它只会在我调用相同的实例化时被覆盖,即每个实例化都有它自己的静态proxy.
不过,以下作品:
#include <cassert>
template < typename F >
decltype(auto) get_ptr(F f)
{
static auto proxy = f; …Run Code Online (Sandbox Code Playgroud) 我正在尝试将Catch单元测试集成到我的项目中,但是对于当前可用的测试来说它失败了
Catch v1.10.0
Generated: 2017-08-26 15:16:46.676990
Run Code Online (Sandbox Code Playgroud)
例:
test.cpp
#include "catch.hpp"
#define CATCH_CONFIG_MAIN
TEST_CASE("CATCH TEST"){
REQUIRE(1 == 1);
}
Run Code Online (Sandbox Code Playgroud)
g++ test.cpp -o test.exe -std=c++11
Run Code Online (Sandbox Code Playgroud)
错误:
Undefined symbols for architecture x86_64:
"Catch::ResultBuilder::endExpression(Catch::DecomposedExpression const&)", referenced from:
Catch::BinaryExpression<int const&, (Catch::Internal::Operator)0, int const&>::endExpression() const in test-b77427.o
"Catch::ResultBuilder::setResultType(bool)", referenced from:
Catch::BinaryExpression<int const&, (Catch::Internal::Operator)0, int const&>::endExpression() const in test-b77427.o
"Catch::ResultBuilder::useActiveException(Catch::ResultDisposition::Flags)", referenced from:
____C_A_T_C_H____T_E_S_T____0() in test-b77427.o
"Catch::ResultBuilder::react()", referenced from:
____C_A_T_C_H____T_E_S_T____0() in test-b77427.o
"Catch::ResultBuilder::ResultBuilder(char const*, Catch::SourceLineInfo const&, char const*, Catch::ResultDisposition::Flags, char const*)", referenced from:
____C_A_T_C_H____T_E_S_T____0() in test-b77427.o …Run Code Online (Sandbox Code Playgroud) 在这段代码中:
RationalNum operator+(const RationalNum& left, const RationalNum& right) {
RationalNum temp;
/*code here*/
return temp;
}
Run Code Online (Sandbox Code Playgroud)
如果在此函数退出时从堆栈中"删除"对象,它如何返回RationalNum对象?
local i1 = 1
print(i1)
local i2 = 1,0
print(i2)
local i3 = 1,
print(i3)
Run Code Online (Sandbox Code Playgroud)
结果:
1
1
nil
Run Code Online (Sandbox Code Playgroud)
为什么i3是零?
我了解到package.preload可以用来将一个脚本公开给其他脚本。
这是我的示例代码。
lua_State *L = luaL_newstate();
luaL_openlibs(L);
lua_settop(L, 0);
//Script A
luaL_dostring(L, "local A = {} package.preload['A'] = function () return A end A.num = 3");
//Script B
luaL_dostring(L, "local A = require 'A' print(A.num)");
lua_close(L);
Run Code Online (Sandbox Code Playgroud)
结果:3
虽然这工作正常,但我想知道 ScriptA的代码是否可以更加简化,或者是否有其他替代解决方案将脚本公开给其他脚本。
补充:我问这个的主要原因是因为我认为package.preload['A'] = function () return A end写起来很长而且很无聊。
我有这个:
function dec2hex(IN)
local OUT
OUT = string.format("%x",IN)
return OUT
end
Run Code Online (Sandbox Code Playgroud)
并且需要IN将零填充到字符串长度 6。
我无法使用String.Utils或PadLeft。它位于一个名为 Watchmaker 的应用程序中,该应用程序使用 Lua 的精简版本。
我试图userdata从chunk AC++中的Lua脚本()(通过我的示例中的函数返回的变量)获取然后,然后从C++(通过我的示例中的函数参数)将其传递userdata回Lua脚本(chunk B),以便userdata可以chunk B像在原来一样使用chunk A.
MyBindings.h
class Vec2
{
public:
Vec2():x(0), y(0){};
Vec2(float x, float y):x(x), y(y){};
float x, y;
};
Run Code Online (Sandbox Code Playgroud)
MyBindings.i
%module my
%{
#include "MyBindings.h"
%}
%include "MyBindings.h"
Run Code Online (Sandbox Code Playgroud)
main.cpp
#include <iostream>
#include <lua.hpp>
extern "C"
{
int luaopen_my(lua_State *L);
}
int main()
{
lua_State *L = luaL_newstate();
luaL_openlibs(L);
luaopen_my(L);
lua_settop(L, 0);
/* chunk A */
luaL_dostring(L, "local vec2 = my.Vec2(3, 4)\n"
"function setup()\n"
"return …Run Code Online (Sandbox Code Playgroud)