我正在尝试实现看起来像这个最小例子的东西:
trait Bar<T> {}
struct Foo<T> {
data: Vec<Box<Bar<T>>>,
}
impl<T> Foo<T> {
fn add<U: Bar<T>>(&mut self, x: U) {
self.data.push(Box::new(x));
}
}
Run Code Online (Sandbox Code Playgroud)
由于Rust默认为(据我所知)pass-by-ownership,我的心理模型认为这应该有效.该add
方法获取对象的所有权,x
并且能够将此对象移动到a中,Box
因为它知道完整类型U
(而不仅仅是特征Bar<T>
).一旦进入a Box
,框内项目的生命周期应该与框的实际生命周期相关联(例如,当pop()
从矢量中删除时,对象将被销毁).
然而,很明显,编译器不同意(我确信比我更了解...),要求我考虑添加一个'static
生命周期限定符(E0310).我99%肯定这不是我想要的,但我不确定我应该做什么.
为了澄清我的想法并帮助识别误解,我的心理模型来自C++背景,是:
Box<T>
本质上是 std::unique_ptr<T>
Copy
否则传递rvalue-reference&
大致const&
和&mut
大致&
过去几天我一直在玩C++ 11,我想出了一些奇怪的东西.
如果我想统一初始化一个int:
int a{5};
Run Code Online (Sandbox Code Playgroud)
但是如果我对std :: vector做同样的事情:
std::vector<int> b{2};
Run Code Online (Sandbox Code Playgroud)
不构造一个两元素数组,而是一个具有一个值为2的元素的数组.似乎要获得这种效果,需要更加明确它:
std::vector<int> c{{2}};
std::vector<int> d = {2};
Run Code Online (Sandbox Code Playgroud)
但不像b的声明 - 这似乎不一致.我已经看到了其他一些相同的效果.我要问的是 - 这是最终C++ 11标准中的这种行为,还是只是在早期实施的草案中?如果是这样,为什么标准委员会会包含这种行为?看起来它破坏了统一初始化的整个目的,因为必须记住哪些类具有初始化列表构造函数,并且只使用old()语法而不是{}.或者一个人放弃统一初始化.
这似乎是一个很大的"陷阱".但是我不知道它可能有优点.
编辑:此代码:
#include <iostream>
#include <vector>
int main() {
std::vector<int> a{2};
for (auto x: a) {
std::cout << x << std::endl;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在gcc 4.6.2上输出"2"
替换这样的东西是合法的:
namespace foo {
namespace bar {
baz();
}
}
Run Code Online (Sandbox Code Playgroud)
用这样的东西:
namespace foo::bar {
baz();
}
Run Code Online (Sandbox Code Playgroud)
?
我正在安装gcc 4.5.2,mpc为0.8.2,mpfr为3.1.0,gmp为5.0.2.我已将每个mpc,mpfr和gmp目录复制到gcc-4.5.2目录中(删除版本标记).GCC成功配置.然而,当我运行make时,我得到:
checking for MPFR... no
configure: error: libmpfr not found or uses a different ABI.
make[1]: *** [configure-mpc] Error 1
make[1]: leaving directory cross/build/gcc
make: *** [all] Error 2
Run Code Online (Sandbox Code Playgroud)
MPFR位于cross/src/gcc-4.5.2/mpfr.MPFR已经成功构建.有谁知道为什么mpc无法配置?
我认为问题可能部分与MPFR的libs/headers在cross/src/gcc-4.5.2/mpfr/src中有关,而不在cross/src/gcc-4.5.2/mpfr中.我所做的只是提取和复制 - 这是默认的目录结构.
我不明白为什么这段代码在不同的实现中表现不同:
(format t "asdf")
(setq var (read))
Run Code Online (Sandbox Code Playgroud)
在CLISP中,它的行为与预期的一样,打印提示后跟读取,但在SBCL中读取,然后输出.我在网上读了一下并改了:
(format t "asdf")
(force-output t)
(setq var (read))
Run Code Online (Sandbox Code Playgroud)
这再次在CLISP中工作正常,但在SBCL中它仍然读取,然后输出.我甚至尝试将它分成另一个函数:
(defun output (string)
(format t string)
(force-output t))
(output "asdf")
(setq var (read))
Run Code Online (Sandbox Code Playgroud)
它仍然读取,然后输出.我没有force-output
正确使用或者这只是SBCL的特质吗?
我一直致力于用几种不同的语言实现Mandelbrot Set.我有一个C++,C#,Java和Python的工作实现,但Common Lisp实现有一些我无法弄清楚的错误.它生成集合,但在管道中的某个地方集合变形.我已经测试并且几乎可以肯定地知道文件I/O CLO不是问题 - 它不太可能但是可能,我已经非常彻底地测试了它.
请注意,这些实现的目的是将它们相互比较 - 所以我试图保持代码实现尽可能相似,以便它们具有可比性.
Mandelbrot集(这里由Python实现生成):
http://www.freeimagehosting.net/uploads/65cb71a873.png http://www.freeimagehosting.net/uploads/65cb71a873.png"Mandelbrot Set(由Python生成)"
但我的Common Lisp程序生成了这个:
http://www.freeimagehosting.net/uploads/50bf29bcc9.png http://www.freeimagehosting.net/uploads/50bf29bcc9.png"Common Lisp版本的扭曲Mandelbrot集"
Clisp和SBCL中的错误相同.
码:
Common Lisp:
(defun mandelbrot (real cplx num_iter)
(if (> (+ (* real real) (* cplx cplx)) 4)
1
(let ((tmpreal real) (tmpcplx cplx) (i 1))
(loop
(setq tmpcplx (+ (* (* tmpreal tmpcplx) 2) cplx))
(setq tmpreal (+ (- (* tmpreal tmpreal) (* tmpcplx tmpcplx))
real))
(setq i (+ i 1))
(cond
((> (+ (* tmpreal …
Run Code Online (Sandbox Code Playgroud) 所以我正在为libgstreamermm-0.10编译示例,我遇到了CMake的问题.
使用我的系统上默认安装的libgstreamermm-0.10版本,示例为segfaults.好的,所以我获得了最新的源代码并将它们安装到/ usr/local并获得了新的示例.一切都很好看.
g++ main.cc player_window.cc -o test `pkg-config --cflags --libs gtkmm-3.0` `pkg-config --cflags --libs gstreamermm-0.10`
Run Code Online (Sandbox Code Playgroud)
工作正常,如预期的那样.很棒,现在尝试让它与CMake很好地配合.我制作了一个快速的CMakeLists.txt文件.我使用pkg-config,因为它工作正常,我真的不想添加一个find模块.所以我的文件看起来像这样:
cmake_minimum_required(VERSION 2.6.2)
project(media_player_gtkmm)
INCLUDE(FindPkgConfig)
set(SOURCES main.cc player_window.cc)
add_executable(media_player_gtkmm ${SOURCES})
#dependencies
pkg_check_modules(GSTMM REQUIRED gstreamermm-0.10)
pkg_check_modules(GTKMM REQUIRED gtkmm-3.0)
include_directories(${GTKMM_INCLUDE_DIRS} ${GSTMM_INCLUDE_DIRS})
link_directories(${GTKMM_LIBRARY_DIRS} ${GSTMM_LIBRARY_DIRS})
target_link_libraries(media_player_gtkmm ${GTKMM_LIBRARIES} ${GSTMM_LIBRARIES})
Run Code Online (Sandbox Code Playgroud)
一切都编译到链接阶段,在那里我得到未定义的符号错误.然后我pkg-config --libs gstreamermm-0.10
用-L/usr/local/lib 查看start 的输出.我查看输出,make VERBOSE=1
并且CMake没有在链接命令中添加-L,即使我有link_directories行.所以,即使我在/ usr/local/include中使用新版gstreamer的头文件,但是当我想要使用/ usr/local/lib中的版本时,正在使用来自/ usr/lib的库. .Pkg-Config似乎已经接受了这一点,并相应地进行了调整,但是CMake,即使我在内部使用pkg-config,也没有接收到链接标志.
我现在可以手动设置链接标志,但这似乎有点像黑客.我确信有更好的方法来指定它.
有没有办法在编译时和运行时实现字符串?
AFAIK用于构造constexpr的类需要有一个简单的析构函数.然而,当我们处理字符串时,这证明是困难的.如果字符串不是constexpr,那么它需要释放内存.但是,如果它是constexpr,那么它是静态分配的,不应该被删除,因此允许一个简单的析构函数.
但是,不可能说"嘿,编译器!如果我是constexpr,你不需要毁掉我!" 或者是吗?
它将类似于以下内容:
class string {
private:
char * str;
public:
template<std::size_t l>
constexpr string(const char (&s)[l]) : str(&(s[0])) {}
string(const char * s) { str = strdup(s); }
static if (object_is_constexpr) {
~string() = default;
}
else {
~string() { free(str); }
}
};
Run Code Online (Sandbox Code Playgroud)
我能得到的最接近的是两个单独的类型,string和constexpr_string,用户定义的文字_string返回constexpr_string,以及用户定义的从constexpr_string到string的隐式转换.
这不是很好,虽然有效,const auto s = "asdf"_string;
但const string s = "asdf"_string;
没有.此外,constexpr_string的引用/指针不会转换.继承任何一种方式都会导致不直观的"问题",并且无法解决第一个问题.
这似乎应该是可能的,只要编译器要信任程序员,constexpr不需要被破坏.
如果我有误解,请告诉我.
为什么这段代码无法编译(未声明的标识符'x',g ++ 4.9和clang ++ 3.5)?
template <class T>
struct base {
int x;
};
template <class U>
struct end : public base<U> {
end() {
x = 5;
}
};
Run Code Online (Sandbox Code Playgroud)
注意:明确指定this->x
可以解决问题.
如果问题标题不准确,我很抱歉 - 但我很难理解这里发生了什么.
考虑以下课程:
struct foo {
foo(foo&);
};
Run Code Online (Sandbox Code Playgroud)
以下没有错误:
void func(foo& f) {
foo bar{f};
}
Run Code Online (Sandbox Code Playgroud)
但是,当我使用auto时:
void func(foo& f) {
auto bar = foo{f};
}
Run Code Online (Sandbox Code Playgroud)
我得到(gcc):
test.cpp: In function ‘void func(foo&)’:
test.cpp:6:21: error: no matching function for call to ‘foo::foo(foo)’
test.cpp:6:21: note: candidate is:
test.cpp:2:5: note: foo::foo(foo&)
test.cpp:2:5: note: no known conversion for argument 1 from ‘foo’ to ‘foo&’
Run Code Online (Sandbox Code Playgroud)
(铛)
test.cpp:6:10: error: no matching constructor for initialization of 'bar'
auto bar = foo{f};
^ ~~~~~~
test.cpp:2:5: note: candidate …
Run Code Online (Sandbox Code Playgroud) c++ ×5
c++11 ×3
common-lisp ×2
auto ×1
cmake ×1
compilation ×1
constexpr ×1
crtp ×1
format ×1
gcc ×1
io ×1
io-buffering ×1
lifetime ×1
linker ×1
lvalue ×1
mandelbrot ×1
mpfr ×1
namespaces ×1
pkg-config ×1
rust ×1
scope ×1
set ×1
templates ×1