小编Sil*_*olo的帖子

C++对象构造方法的区别

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上进行编译.这并没有把我当作编译器错误,但以防万一......

c++ string constructor c++11

20
推荐指数
1
解决办法
1025
查看次数

带有两个不同类型参数的隐式模板类型推导

假设以下情况:

类型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

15
推荐指数
3
解决办法
1123
查看次数

Eval-何时使用?

在阅读了很多关于Lisp eval-when运算符的文档后,我仍然无法理解它的用法,我知道使用这个运算符我可以控制表达式的评估时间,但是我无法弄清楚这可能适用的任何例子?

最诚挚的问候,utxeee.

lisp macros compilation common-lisp eval-when

12
推荐指数
1
解决办法
1973
查看次数

公共"使用"= decltype(<private>)

在下面(最小化)代码中,我有一个公开using声明,指的是decltype(something_private):using Foo = decltype(something_private<T>).

在Clang但不是GCC,因为它是私有的,所以不会编译.

问题:

  1. 如果我不想func<T>()公开,什么是优雅的解决方案.
  2. 在C++标准(C++ 11)中,备份Clang在这里是正确的吗?

以下代码在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)

c++ templates decltype language-lawyer c++11

12
推荐指数
1
解决办法
333
查看次数

循环宏中的Common Lisp绑定

我想在循环中重新绑定一个特殊变量.现在,通常,这是使用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*变量,或者是否存在可能创建同名新词法变量的风险?

loops common-lisp let dynamic-scope

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

Common Lisp特殊快捷方式字符

在Common Lisp中,显然有一些特殊字符可以作为某些表单的快捷方式.'x手段(quote x).#'f手段(function f).我曾经认为那些(以及反击)是唯一的,但后来我了解到#(),这显然是一个载体,就在今天有人提到过#.,这显然与评估时间有关.

尽我所能,我似乎无法找到一个完整的列表,其中的前缀符号意味着什么,他们做什么?这是由实施决定的东西,还是有人可以指向我在标准中的某个地方全面列出这些快捷方式?

lisp common-lisp syntactic-sugar

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

为什么“临时是块末尾表达式的一部分”是一个错误?

这可能是我不理解借用检查器的一些技术细节的教科书案例,但如果有人能帮我解决这个问题会很好。

我有这个(令人难以置信的简化)代码块,它编译得非常好。

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)

temporary rust borrow-checker

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

如何正确地对 Pair 对象的值侧进行解容器

我正在Pair循环中构建多个对象,并且对每个对象的值使用相同的标量变量(尽管具有不同的值)。

\n

作为我正在做的事情的简化示例,请考虑

\n
my @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)

raku raku-container

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

Haskell仅为读访问的导出记录

我有一个使用记录语法的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)

但这似乎是解决问题的一种相当迂回的方式.有没有办法继续使用记录语法,只导出记录名称以进行读取访问,而不是写入访问?

haskell encapsulation record accessor

7
推荐指数
1
解决办法
398
查看次数

假装一个自动加载的函数有一个块原型

假设我有一个以 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)

perl

7
推荐指数
1
解决办法
318
查看次数