小编Eri*_*ler的帖子

可以轻松检测__VA_OPT__支持?

在C++ 20中,__VA_OPT__如果参数的数量大于零,则预处理器支持作为可选地扩展可变参数宏中的标记的方法.(这消除了对##__VA_ARGS__GCC扩展的需求,这是一个不可移植且丑陋的黑客.)

Clang SVN已实现此功能,但尚未为其添加功能测试宏.任何聪明的预处理器黑客能否找到一种方法来检测__VA_OPT__支持的存在与否,而不会导致硬错误或可移植性警告?

c++ c-preprocessor c++20

25
推荐指数
3
解决办法
3737
查看次数

BOOST_PP_SEQ_FOLD_LEFT如何工作?

我需要编写一个处理任意长的事情列表的宏(A)(B)(C).如果我可以采用Boost依赖,我只会使用一个BOOST_PP_SEQ_宏系列.不幸的是,我不能这样,我只是想弄清楚它是如何工作的.这个东西并不明显.

这里的任何人都可以写一个简单的,独立的实现,比方说,BOOST_PP_SEQ_FOLD_LEFT让我来看看吗?特别是,我想改造:

template_(class A, class B, class C)(
    requires IsFoo<A> && IsBar<B>)(
    requires IsBaz<C>)
void frobozzle(A, B, C);
Run Code Online (Sandbox Code Playgroud)

被改写为:

template<class A, class B, class C,
    int dummy = 0,
    std::enable_if_t<dummy == 0 && (IsFoo<A> && IsBar<B>), int> = 0,
    std::enable_if_t<dummy == 0 && (IsBaz<C>), int> = 0>
void frobozzle(A, B, C);
Run Code Online (Sandbox Code Playgroud)

可以有任意数量的requires条款,他们应该各自得到自己的条款enable_if_t.我让它使用了一个requires子句,但是我在这个过程中耗尽了我的C预处理器.

假设一个符合标准的预处理器是可以的,因为我不需要MSVC支持.

c c++ c-preprocessor

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

boost :: mpl :: for_each没有实例化

以下面的例子,我想知道是否有一个替代品boost::mpl::for_each,它可以在没有任何参数的情况下调用Functor.

#include <boost/mpl/vector.hpp>
#include <boost/mpl/for_each.hpp>

struct EasyFixEngineA { static const char* const name() { return "a"; } };
struct EasyFixEngineB { static const char* const name() { return "b"; } };

struct Registrator {
    // Would prefer a template<class T> void operator()()
    template<class T> void operator()(T t) {
        RegisterInFactory<EasyFixEngine, T> dummy(T::name());
    }
};

// ...
typedef boost::mpl::vector<EasyFixEngineA,EasyFixEngineB> Engines;
boost::mpl::for_each<Engines>(Registrator());
Run Code Online (Sandbox Code Playgroud)

它似乎for_each是默认实例化类型.

c++ boost boost-mpl

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

来自boost.lambda或boost.phoenix的静态函数

我经常使用boost.lambda(和phoenix)在C++中定义lambda函数.我非常喜欢它们的多态属性,它们表示的简单性以及它们在C++中进行函数式编程的方式变得如此简单.在某些情况下,它甚至更清晰,更易读(如果您习惯于阅读它们),可以使用它们来定义小函数并在静态范围内命名它们.

存储这些类似于传统功能的功能的方法最多的是捕获它们 boost::function

const boost::function<double(double,double)> add = _1+_2;
Run Code Online (Sandbox Code Playgroud)

但问题是这样做的运行时效率低下.即使add这里的函数是无状态的,返回的lambda类型也不是空的并且它sizeof大于1(因此boost::function默认的ctor和copy ctor将涉及new).我真的怀疑编译器或boost方面有一种机制来检测这种无状态并生成相当于使用的代码:

double (* const add)(double,double) = _1+_2; //not valid right now
Run Code Online (Sandbox Code Playgroud)

当然可以使用c ++ 11 auto,但是变量不能在非模板化的上下文中传递.我终于设法做了我想要的,使用以下方法:

#include <boost/lambda/lambda.hpp>
using namespace boost::lambda;

#include <boost/type_traits.hpp>
#include <boost/utility/result_of.hpp>
using namespace boost;


template <class T>
struct static_lambda {

    static const T* const t;

    // Define a static function that calls the functional t
    template <class arg1type, class arg2type>
    static typename result_of<T(arg1type,arg2type)>::type 
        apply(arg1type arg1,arg2type arg2){
        return (*t)(arg1,arg2); 
    } …
Run Code Online (Sandbox Code Playgroud)

c++ lambda boost boost-phoenix boost-proto

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

如何在命名空间范围内转发声明constexpr对象?

在clang(trunk)上我可以转发声明一个稍后定义的对象,constexpr如下所示:

// Fwd-declarations
struct S;
extern const S s;

// (... later) definitions
struct S {};
constexpr S s {};
Run Code Online (Sandbox Code Playgroud)

Gcc 4.8不喜欢这样,告诉我前向声明和定义在constexpr-ness中有所不同.是gcc说实话,还是这只是一个gcc bug?

c++ gcc clang c++11

8
推荐指数
2
解决办法
2232
查看次数

在MACRO(X)(Y)中翻转X和Y的顺序

我有一个基于C++宏的DSL,它定义了一个像这样的宏:

#define RETURNS(...) \
    enable_if_t<__VA_ARGS__ WHEN

#define WHEN(...) \
    , EAT_ ## __VA_ARGS__ >

#define EAT_requires
Run Code Online (Sandbox Code Playgroud)

这是用于:

template<class T>
auto some_function(T t) ->
    RETURNS(int)
        (requires SomeConcept<T>)
Run Code Online (Sandbox Code Playgroud)

其中扩展为:

template<class T>
auto some_function(T t) ->
    enable_if_t<int, SomeConcept<T>>
Run Code Online (Sandbox Code Playgroud)

(当启用C++ 20概念时,这会扩展为实际requires子句.)

我希望翻转参数的顺序.也就是说,我希望它产生这个:

template<class T>
auto some_function(T t) ->
    enable_if_t<SomeConcept<T>, int>
Run Code Online (Sandbox Code Playgroud)

我认为这是不可能的.一些聪明的PP黑客可以证明我错了吗?

c++ c-preprocessor

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

clang-query:检查函数参数类型的模板参数的名称

我有一个大项目,以及一系列 C++ 类成员函数,形式如下:

Return CClass::MemberFunction(
   Arg1 arg1,
   //...
   std::weak_ptr<IMemberFunctionListenerInterface> listener) {
//...
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试编写一个匹配器来查找这些函数,这些函数的参数类型在其名称中包含字符串“Listener”。

我可以找到参数类型weak_ptr在其名称中带有“ ”的函数:

clang-query> m cxxMethodDecl(hasAnyParameter(hasType(cxxRecordDecl(matchesName("weak_ptr")))))
Run Code Online (Sandbox Code Playgroud)

这与上面的函数匹配得很好。但是,如果我更改"weak_ptr""Listener",则不再匹配该功能。我猜这是因为它是std::weak_ptr类模板的模板参数的名称。

我已经尝试了这个查询的许多不同变体,但我没有找到与我感兴趣的函数相匹配的变体。

任何指针?

c++ clang abstract-syntax-tree clang-ast-matchers

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

cmake使用macos上的makefile生成器创建的<target> .dSYM目录中有什么?

我在MacOS上使用CMake为我的C++项目生成Makefile.当我构建一个目标(比如说test/AsyncTest)时,我得到了那个目标,加上一个test/AsyncTest.dSYM/包含以下内容的目录:

test/AsyncTest.dSYM/Contents/Resources/DWARF/AsyncTest
test/AsyncTest.dSYM/Contents/Info.plist
Run Code Online (Sandbox Code Playgroud)

我猜这是调试信息(基于".dSYM"和"DWARF"线索),但我还没有找到一个工具让我检查AsyncTest文件.dwarfdump不认识它.

那么,这个文件究竟是什么?有没有一个工具可以用来转储符号信息(假设它是什么)?当我没有要求时,为什么CMake会产生它呢?我可以生成它(因为生成的文件是huuuuge)?

cmake dwarf dsym

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