我尝试获取发送到可变参数宏的第一个实际参数.这是我试过的,哪些在VS2010中不起作用:
#define FIRST_ARG(N, ...) N
#define MY_MACRO(...) decltype(FIRST_ARG(__VA_ARGS__))
Run Code Online (Sandbox Code Playgroud)
当我查看预处理器输出时,我看到FIRST_ARG返回发送给MY_MACRO... 的整个参数列表
另一方面,当我尝试:
FIRST_ARG(1,2,3)
Run Code Online (Sandbox Code Playgroud)
它按预期扩展到1.
这似乎是臭名昭着的两级concat宏解决问题的逆转.我知道"宏参数在插入宏体之前已完全展开"但这似乎对我没有帮助,因为我不明白这意味着什么......和__VA_ARGS__
显然是__VA_ARGS__绑定,N只是稍后评估.我尝试了几种额外的宏观方法,但没有用.
这个问题是关于new [] int和new [] int()的语义和性能的差异,以及在向allocator_traits :: construct()添加ctor参数的完美转发时可能无意中创建的从第一个到第二个措辞的变化.这个问题并不涉及一个非常明显的问题,即默认ctor运行在由向量的resize()构造的所有新元素上.
对我来说,在resize中清除内置类型向量的元素似乎是浪费.但是实现VS2012以便调整大小(n)并且因此具有count参数的构造函数实际上将分配的值数组设置为0.
我也在标准中找到了对此的支持(http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2012/n3485.pdf),但我认为这可能是一个错误因为它依赖于最近涉及完美转发的条款:
第507页:
template <class T, class... Args>
static void construct(Alloc& a, T* p, Args&&... args);
Run Code Online (Sandbox Code Playgroud)
5 E ff ects:invokes
::new (static_cast<void*>(p)) T(std::forward<Args>(args)...).
Run Code Online (Sandbox Code Playgroud)
并且由于新的int()必须根据同一文档的第191页的第11节将值设置为0,因此向量中的浪费实现是正确的.
问题是标准委员会是否真的希望构造调用的空参数包导致从默认构造到基本类型的值构造的行为发生变化.
我想知道用于构建例如元组的经典递归模式是否应该使用一个常规模板参数或者是否需要两个.这是一个参数案例:
// Forward declaration of main tuple class template.
template<typename... Ds> class Tuple;
// Tuple class specialization for the general case
template<typename D, typename... Ds> class Tuple<D, Ds...> {
public:
typedef D HeadType;
typedef Tuple<Ds...> TailType;
Tuple() {}
Tuple(const D& head, const Ds&... ds) : mHead(head), mTail(ds...) {}
HeadType mHead;
TailType mTail;
};
// Sentinel one element case
template<typename D> class Tuple<D> {
public:
typedef D HeadType;
Tuple() {}
Tuple(const D& d) : mHead(d) {}
HeadType mHead;
};
Run Code Online (Sandbox Code Playgroud)
在这里你可以争辩说,当用一个模板参数实例化(直接或在递归中)时:Tuple<int> …