我正在创建一个函数(可能是成员函数,而不是它很重要......也许它确实?)需要接受未知数量的参数,但我希望它们都是相同的类型.我知道我可以传入数组或向量,但我希望能够直接接受args列表而无需额外的结构甚至是额外的括号.看起来variadic函数本身并不是类型安全的,我不知道如何使用这个w/variadic模板函数.这基本上就是我的目标(更可能不是正确的代码,完全不是为了获取龙的列表,哈哈):
//typedef for dragon_list_t up here somewhere.
enum Maiden {
Eunice
, Beatrice
, Una_Brow
, Helga
, Aida
};
dragon_list_t make_dragon_list(Maiden...) {
//here be dragons
}
Run Code Online (Sandbox Code Playgroud)
要么
template<Maiden... Maidens> dragon_list_t make_dragon_list(Maidens...) {
//here be dragons
}
Run Code Online (Sandbox Code Playgroud)
用法
dragon_list_t dragons_to_slay
= make_dragon_list(Maiden.Eunice, Maiden.Helga, Maiden.Aida)
;
Run Code Online (Sandbox Code Playgroud)
尝试了类似于上面的一些事情,没有骰子.建议?我可能做出明显的疏忽?我知道这样做可能不是一件大事:
dragon_list_t make_dragon_list(std::array<Maiden> maidens) {
//here be dragons.
}
dragon_list_t dragons_to_slay
= make_dragon_list({Maiden.Eunice, Maiden.Helga, Maiden.Aida})
;
Run Code Online (Sandbox Code Playgroud)
但如果可能的话,我宁愿能够以第一种方式做到这一点.
我想知道一个右值引用成员有什么用
class A {
// ...
// Is this one useful?
Foo &&f;
};
Run Code Online (Sandbox Code Playgroud)
与左值参考成员相比,它有任何好处或缺点吗?什么是它的主要用途?
想像:
S f(S a) {
return a;
}
Run Code Online (Sandbox Code Playgroud)
为什么不允许别名a
和返回值槽?
S s = f(t);
S s = t; // can't generally transform it to this :(
Run Code Online (Sandbox Code Playgroud)
如果复制构造函数S
具有副作用,则规范不允许此转换.相反,它需要至少两个副本(一个来自t
于a
,一个来自a
于返回值,另一个是返回值s
,且只有最后一个可以省略.请注意,我写了= t
上述表示的副本的事实的t
到f的a
,这仍然是在移动的副作用存在强制性的唯一拷贝/拷贝构造函数).
这是为什么?
我不小心把我的函数定义的左大括号放在return语句之后
int id(int k) return k; { }
Run Code Online (Sandbox Code Playgroud)
但GCC回答了一个奇怪的错误消息
错误:不再支持命名返回值
任何人都可以解释这个奇怪的功能可能是什么?我从来没有听说过.
我有这个代码
template<int N, bool C = true>
struct A;
template<int N>
struct A<N, !(N % 5)> {
/* ... */
};
// should work
A<25> a;
Run Code Online (Sandbox Code Playgroud)
也就是说,对于N
可被整除的数字,5
编译器应使用部分特化.但编译器不会接受部分特化,因为标准要求它拒绝这样的代码,其中部分特化的非类型参数引用参数而不仅仅是一个参数(比如,A<N, N>
是有效的).但是这样做的原因是什么?
请注意,我可以简单地将我的代码更改为更罗嗦的示例,它是有效的
template<bool> struct wrap;
template<int N, typename = wrap<true> >
struct A;
template<int N>
struct A<N, wrap<!(N % 5)> > {
/* ... */
};
// should work
A<25> a;
Run Code Online (Sandbox Code Playgroud)
这很好,因为它不再是非类型参数.但是,规范禁止更直接的部分专业化的原因是什么?
如果对表达式的求值导致C中的未定义行为,并且在执行程序时总是计算表达式(例如,如果它出现在开头main
),那么如果实现在编译时拒绝它,它是否符合要求?在编译/翻译程序和执行程序之间,C有区别吗?
我知道有C的口译员.他们如何按照C标准处理这种差异?
示例(读取未初始化的本地)
Run Code Online (Sandbox Code Playgroud)int main() { int i; return i; }
在运行它时,在执行的任何阶段(甚至在main
调用之前),程序都可以做一些有趣的事情.但是,当我们甚至没有试图运行它时,还会发生一些有趣的事吗?它会在编译器本身导致缓冲区溢出吗?
出于某种原因,我认为C++ 0x允许std::initializer_list
作为函数的函数参数,例如,期望可以从这样构造的类型std::vector
.但显然,它不起作用.这只是我的编译器,还是永远不会起作用?是因为潜在的重载解决问题吗?
#include <string>
#include <vector>
void function(std::vector<std::string> vec)
{
}
int main()
{
// ok
std::vector<std::string> vec {"hello", "world", "test"};
// error: could not convert '{"hello", "world", "test"}' to 'std::vector...'
function( {"hello", "world", "test"} );
}
Run Code Online (Sandbox Code Playgroud) 今天我发现了这段代码
#include <cstdio>
auto terminal = [](auto term)
{
return [=] (auto func)
{
return terminal(func(term));
};
};
Run Code Online (Sandbox Code Playgroud)
令人惊讶的是,GCC接受了它.Clang拒绝它,因为它terminal
在自己的初始化器中使用并被声明auto
.
我期待clang给出的错误,但它实际上是不正确的吗?或者必须接受代码?
我看到decltype(x)
在宏中使用的x
是一个变量名,因为在宏内部不知道对象的类型.
例如:
decltype(x) y = expr;
Run Code Online (Sandbox Code Playgroud)
我可以轻松使用auto
而不是decltype
.那么decltype
变量类型声明需要哪些情况而不是auto
?
别名模板(14.5.7)可以明确专门化(14.7.3)吗?
我的标准fu失败了,我找不到要测试的编译器.
文本"当模板ID引用别名模板的特化时"意味着是,但是然后该示例似乎引用了其他内容,暗示没有.
NB.我在n3242工作,一个在FDIS后面,其中这一部分的标题是"别名模板".大声笑.