小编Hen*_*nke的帖子

什么是"例外呕吐"?

最近在CodeReview.SE上,我遇到了一个回答,谈到了一种叫做"异常呕吐"的技术.显然,这个技巧用于利用必须以线程安全的方式实现异常,而不管编译器是否支持thread_local变量.

我粘贴以下答案的一部分:

现有的技术并不相同,称为"异常呕吐".注意:

void f(void(*p)()) {
    p();
}
template<typename F> void real_f(F func) {
    try {
        throw func;
    } catch(...) {
        f([] {
            try {
                throw;
            } catch(F func) {
                func();
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

这滥用了这样的事实:编译器必须为复杂对象提供线程局部堆栈以用作异常存储,而不管它们是否支持其他线程本地特性,因此可以获得广泛的编译器支持.最明显的缺点是a)它太可怕了,b)它仅限于堆栈语义.

我的问题是,这个技巧实际上是如何运作的,它是"安全的"吗?

c++ exception-handling thread-safety

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

使C++ 14 constexpr函数与C++ 11兼容

我写了一个类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

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

如何在检测成语中要求精确的函数签名?

假设我有一个类型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.如何避免隐式转换从intsize_t要发生?

c++ templates types type-conversion c++11

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

编译器是否为每个lambda生成不同的类型?

免责声明: 请勿在此问题中使用该代码.它调用未定义的行为.问题的核心陈述,编译器是否为每个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)

c++ lambda templates c++14

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

Catch失败就简单的例子而言

我正在尝试将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)

c++ c++11 catch-unit-test

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

C++运算符重载返回

在这段代码中:

RationalNum operator+(const RationalNum& left, const RationalNum& right) {
    RationalNum temp;
    /*code here*/
    return temp;
}
Run Code Online (Sandbox Code Playgroud)

如果在此函数退出时从堆栈中"删除"对象,它如何返回RationalNum对象?

c++

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

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

Lua 中的 package.preload 替代方案?

我了解到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写起来很长而且很无聊。

c++ lua

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

用零填充十六进制字符串以达到 6 个字符的长度

我有这个:

function dec2hex(IN)
  local OUT
  OUT = string.format("%x",IN)
  return OUT
end
Run Code Online (Sandbox Code Playgroud)

并且需要IN将零填充到字符串长度 6。

我无法使用String.UtilsPadLeft。它位于一个名为 Watchmaker 的应用程序中,该应用程序使用 Lua 的精简版本。

string formatting lua padding

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

如何在C++中将userdata从一个Lua块传递到另一个Lua块

我试图userdatachunk 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)

c++ lua swig lua-userdata

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