在C++ 20中,__VA_OPT__
如果参数的数量大于零,则预处理器支持作为可选地扩展可变参数宏中的标记的方法.(这消除了对##__VA_ARGS__
GCC扩展的需求,这是一个不可移植且丑陋的黑客.)
Clang SVN已实现此功能,但尚未为其添加功能测试宏.任何聪明的预处理器黑客能否找到一种方法来检测__VA_OPT__
支持的存在与否,而不会导致硬错误或可移植性警告?
我需要编写一个处理任意长的事情列表的宏(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支持.
以下面的例子,我想知道是否有一个替代品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
是默认实例化类型.
我经常使用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) 在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++宏的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++ 类成员函数,形式如下:
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
类模板的模板参数的名称。
我已经尝试了这个查询的许多不同变体,但我没有找到与我感兴趣的函数相匹配的变体。
任何指针?
我在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)?