C++中不同的构造语法总是让我感到困惑.在另一个问题中,有人建议尝试初始化一个字符串
std::string foo{ '\0' };
Run Code Online (Sandbox Code Playgroud)
这有效并产生预期结果:长度为1的字符串仅包含空字符.在测试代码时,我不小心输入了
std::string foo('\0');
Run Code Online (Sandbox Code Playgroud)
这编译很好(即使没有警告-Wall
),但在运行时终止
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_M_construct null not valid
Aborted (core dumped)
Run Code Online (Sandbox Code Playgroud)
现在,据我所知,没有构造为std::string
接受一个字符作为参数,而这一假设是进一步证实了,当我试图通过间接的角色.
char b = '\0';
std::string a(b);
Run Code Online (Sandbox Code Playgroud)
这会产生一个很好的,冗长的编译错误.就像这样
std::string a('z');
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:什么允许std::string a('\0');
编译,以及它与什么不同std::string a{ '\0' };
?
脚注:g++
在Ubuntu上进行编译.这并没有把我当作编译器错误,但以防万一......
假设以下情况:
类型A
和类型B
,B
可以隐式转换为A
但反之则是不真实的.
我有一个功能
template<class T>
void do_stuff(T a, T b);
Run Code Online (Sandbox Code Playgroud)
我想这样调用所述函数:
do_stuff(A{}, B{});
Run Code Online (Sandbox Code Playgroud)
这里的问题是编译器无法推断出类型,而是说:
template argument deduction/substitution failed
Run Code Online (Sandbox Code Playgroud)
我可以这样调用我的函数:
do_stuff<A>(A{}, B{});
Run Code Online (Sandbox Code Playgroud)
但这对用户来说更烦人.
或者我可以做这样的事情:
template<class T, class M>
void do_stuff(T a, M b);
Run Code Online (Sandbox Code Playgroud)
但是b继续以它的快乐方式成为B类(具有先前的调用).
理想情况下,我想要像:
template<class T, class M = T>
void do_stuff(T a, M b);
Run Code Online (Sandbox Code Playgroud)
要么:
template<class T@INSERT MAGIC SO THAT T IS DEDUCED AS BEING THE TYPE OF ARGUMENT NR 1@>
void do_stuff(T a, T b);
Run Code Online (Sandbox Code Playgroud)
这样的事情可能吗?
c++ templates metaprogramming template-meta-programming c++17
在阅读了很多关于Lisp eval-when
运算符的文档后,我仍然无法理解它的用法,我知道使用这个运算符我可以控制表达式的评估时间,但是我无法弄清楚这可能适用的任何例子?
最诚挚的问候,utxeee.
在下面(最小化)代码中,我有一个公开using
声明,指的是decltype(something_private)
:using Foo = decltype(something_private<T>)
.
在Clang但不是GCC,因为它是私有的,所以不会编译.
问题:
func<T>()
公开,什么是优雅的解决方案.以下代码在Clang(3.9 - 7.0)上出现以下错误代码失败,但构建在GCC(4.8.4 - 8.2)上:
class A {
private:
template <class T>
static auto func() -> T; // The actual return type is much
// more complicated, so `using Foo = T` would not work.
public:
template <class T>
using Foo = decltype(func<T>());
};
int main(int, char**) {
A::Foo<int> y;
return y;
}
Run Code Online (Sandbox Code Playgroud)
Clang 7.0输出:
<source>:10:24: error: 'func' is a private member of …
Run Code Online (Sandbox Code Playgroud) 我想在循环中重新绑定一个特殊变量.现在,通常,这是使用a完成的let
.
(let ((*read-eval* nil))
(do-something-here))
Run Code Online (Sandbox Code Playgroud)
但由于loop
宏有这些好的with
条款,我想我可能会在那里这样做.表达式(macroexpand '(loop with *read-eval* = nil))
最终将绑定扩展为a let
,因此它肯定会对我的实现有所帮助.但我在标准中找不到任何表明这是标准化行为的内容.所以,我想,我的问题是:
(loop with *read-eval* = nil
for i from 1 to 10
do (something-involving-the-read-function))
Run Code Online (Sandbox Code Playgroud)
是否需要符合实现来修改现有*read-eval*
变量,或者是否存在可能创建同名新词法变量的风险?
在Common Lisp中,显然有一些特殊字符可以作为某些表单的快捷方式.'x
手段(quote x)
.#'f
手段(function f)
.我曾经认为那些(以及反击)是唯一的,但后来我了解到#()
,这显然是一个载体,就在今天有人提到过#.
,这显然与评估时间有关.
尽我所能,我似乎无法找到一个完整的列表,其中的前缀符号意味着什么,他们做什么?这是由实施决定的东西,还是有人可以指向我在标准中的某个地方全面列出这些快捷方式?
这可能是我不理解借用检查器的一些技术细节的教科书案例,但如果有人能帮我解决这个问题会很好。
我有这个(令人难以置信的简化)代码块,它编译得非常好。
pub struct Example(pub Vec<String>);
impl Example {
pub fn iter(&self) -> impl Iterator<Item=&String> {
self.0.iter()
}
}
pub fn some_condition(_: &str) -> bool {
// This is not important.
return false;
}
pub fn foo() -> bool {
let example = Example(vec!("foo".to_owned(), "bar".to_owned()));
let mut tmp = example.iter();
tmp.all(|x| some_condition(x))
}
pub fn main() {
println!("{}", foo());
}
Run Code Online (Sandbox Code Playgroud)
但是,我尝试的第一件事(在我看来,应该等同于上述内容)是tmp
完全删除临时变量,如下所示
pub fn foo() -> bool {
let example = Example(vec!("foo".to_owned(), "bar".to_owned()));
example.iter().all(|x| some_condition(x))
}
Run Code Online (Sandbox Code Playgroud)
但是这个版本会产生以下错误。
pub struct …
Run Code Online (Sandbox Code Playgroud) 我正在Pair
循环中构建多个对象,并且对每个对象的值使用相同的标量变量(尽管具有不同的值)。
作为我正在做的事情的简化示例,请考虑
\nmy @list;\nmy $acc = \'\';\n\nfor 1..30 -> $i {\n if $i % 5 == 4 {\n @list.push($i => $acc);\n $acc = \'\';\n } else {\n $acc = "$acc $i";\n }\n}\n\nsay @list;\n
Run Code Online (Sandbox Code Playgroud)\n(当然,我的实际代码更复杂,并且从文件而不是预定义范围中读取,因此我不能像理论上那样完全消除循环)
\n我们累积包含写出的数字序列的字符串,创建一个将某些数字映射到低于该数字的值序列的对。
\n我希望这个程序的输出是
\n[4 => 1 2 3 9 => 5 6 7 8 14 => 10 11 12 13 19 => 15 16 17 18 24 => 20 21 22 23 29 => 25 26 27 …
Run Code Online (Sandbox Code Playgroud) 我有一个使用记录语法的Haskell类型.
data Foo a = Foo { getDims :: (Int, Int), getData :: [a] }
Run Code Online (Sandbox Code Playgroud)
我不想导出Foo
值构造函数,因此用户无法构造无效对象.但是,我想导出getDims
,以便用户可以获取数据结构的维度.如果我这样做
module Data.ModuleName(Foo(getDims)) where
Run Code Online (Sandbox Code Playgroud)
然后用户可以使用getDims
获取维度,但问题是他们还可以使用记录更新语法来更新字段.
getDims foo -- This is allowed (as intended)
foo { getDims = (999, 999) } -- But this is also allowed (not intended)
Run Code Online (Sandbox Code Playgroud)
我想阻止后者,因为它会将数据置于无效状态.我意识到我可以根本不使用记录.
data Foo a = Foo { getDims_ :: (Int, Int), getData :: [a] }
getDims :: Foo a -> (Int, Int)
getDims = getDims_
Run Code Online (Sandbox Code Playgroud)
但这似乎是解决问题的一种相当迂回的方式.有没有办法继续使用记录语法,只导出记录名称以进行读取访问,而不是写入访问?
假设我有一个以 sub 作为参数的子例程。
sub foobar {
my $block = shift;
$block->();
}
Run Code Online (Sandbox Code Playgroud)
然后我可以这样称呼它
foobar(sub { print "Hello :)\n" });
Run Code Online (Sandbox Code Playgroud)
如果我用适当的原型声明它,我也可以使用块语法。
sub foobar(&) {
my $block = shift;
$block->();
}
foobar { print "Hello :)\n" };
Run Code Online (Sandbox Code Playgroud)
现在,假设我的函数实际上并不存在并且是一个 AUTOLOAD,例如
sub AUTOLOAD {
$AUTOLOAD =~ s/.*:://;
if ($AUTOLOAD eq "foobar") {
my $block = shift;
$block->();
} else {
die("No such function $AUTOLOAD");
}
}
Run Code Online (Sandbox Code Playgroud)
我们仍然可以使用显式调用它 sub
foobar(sub { print "Hello :)\n" });
Run Code Online (Sandbox Code Playgroud)
我们可以通过预先声明子程序来消除不必要的括号。
use subs 'foobar';
foobar sub { print "Hello :)\n" …
Run Code Online (Sandbox Code Playgroud)