我知道在C++中我们可以这样做:
class A {} a;
Run Code Online (Sandbox Code Playgroud)
这使得一个A名为的对象a.它相当于:
A a;
Run Code Online (Sandbox Code Playgroud)
我想知道如何用模板做这件事.例如:
template <typename T> struct N {} <int> n;
Run Code Online (Sandbox Code Playgroud)
这不会编译,但你明白了.如何为与其类定义内联创建的对象指定模板参数?这甚至可能吗?
void f(int x = decltype(x){});
Run Code Online (Sandbox Code Playgroud)
gcc中的错误表示x未在此范围内声明,但根据3.3.2/1,变量x应在范围内:
声明的声明就在其完整的声明者(第8条)之后和初始化者(如果有的话)之前,除非如下所述.[例:
Run Code Online (Sandbox Code Playgroud)int x = 12; { int x = x; }这里第二个
x用自己的(不确定的)值初始化. - 结束例子]
clang是否正确?应该x可以在自己的初始化程序中访问?
PS:int x = x作为参数在两个编译器中都失败但我不知道为什么.
s->duplicate()返回一个类型的对象Box*,但是我在初始化时遇到错误Box*.看起来它正在被转换回来Shape*.如果将协变返回类型转换回基类指针,有什么意义?:
struct Shape
{
virtual Shape* duplicate()
{
return new Shape;
}
};
struct Box : Shape
{
virtual Box* duplicate()
{
return new Box;
}
};
int main()
{
Shape* s = new Box;
Box* b = s->duplicate();
}
Run Code Online (Sandbox Code Playgroud)
错误:
main.cpp:22:12: error: cannot initialize a variable of type 'Box *' with an rvalue of type 'Shape *'
Box* b = s->duplicate();
^ ~~~~~~~~~~~~~~
1 error generated.
Run Code Online (Sandbox Code Playgroud) 这个问题与前面的C++ 11标准(C++ 03)有关.explicit防止从一种类型到另一种类型的隐式转换.例如:
struct Foo
{
explicit Foo(int);
};
Foo f = 5; // will not compile
Foo b = Foo(5); // works
Run Code Online (Sandbox Code Playgroud)
如果我们有一个带有两个或更多参数的构造函数,会explicit阻止什么?我知道在C++ 11中你已经进行了初始化,因此它会阻止构造,例如:
struct Foo
{
explicit Foo(int, int);
};
Foo f = {4, 2}; // error!
Run Code Online (Sandbox Code Playgroud)
但是在C++ 03中我们没有支持初始化,所以explicit关键字阻止了什么类型的构造呢?
据我所知,当从函数返回-value对象时,会调用它们的copy-constructors.如果类具有已删除的复制构造函数,则按值返回将失败.
struct X {
X(const X &) = delete;
};
X f() {
return X{};
}
Run Code Online (Sandbox Code Playgroud)
error: call to deleted constructor of 'X'
C++ 11为我们提供了扩展初始化器.我在SO帖子的某个地方读到了这个
X f() {
return {};
}
Run Code Online (Sandbox Code Playgroud)
是相同的
X f() {
return X{};
}
Run Code Online (Sandbox Code Playgroud)
那么为什么下面的代码没有给我一个错误?它通过了,我甚至可以在main中调用该函数:
struct D {
D(const D &) = delete;
};
D f() { return {}; }
int main()
{
f();
}
Run Code Online (Sandbox Code Playgroud)
这是一个演示.没有报告错误.我发现这很奇怪,因为我认为应该调用copy-constructor.任何人都可以解释为什么没有给出错误?
我有这个简单的程序,适用于线程.在Clang我得到了一堆令人困惑的无关错误.这是程序:
#include <iostream>
#include <thread>
#include <future>
int main()
{
std::packaged_task<int()> task([] { return 1; });
std::future<int> result = task.get_future();
task();
std::cout << "Result was: " << result.get();
}
Run Code Online (Sandbox Code Playgroud)
错误:
错误:没有用于初始化'duration'的匹配构造函数(又名'
std::chrono::duration<long, std::ratio<1, 1000000> >'):_ d( _t.time_since_epoch())注意:在'std::chrono::time_point<std::chrono::system_clock, std::chrono::duration<long, std::ratio<1, 1000000> > >::time_point<std::chrono::duration<long, std::ratio<1, 1000000000> > >'此处请求的函数模板特化的实例化
还有更多,但你可以在程序的这个链接中看到它.奇怪的是,它在g ++ 4.7.3和4.6.3中编译得很好.为什么这只发生在Clang?
更新:正如大卫指出的那样,当我包含<future>标题时,似乎只会失败.
在Coursera的普林斯顿教程中,讲师解释了遇到的常见增长顺序函数.他说线性和线性运行时间是"我们努力的",他的推理是随着输入尺寸的增加,运行时间也增加.我认为这是他犯了一个错误的地方,因为我之前听过他提到线性增长顺序对于一个有效的算法是不能令人满意的.
在他讲话时,他还展示了绘制不同运行时间的图表 - 恒定和对数运行时间看起来效率更高.这是一个错误,还是这个?
当我运行此代码时:
#include <iostream>
#include <thread>
#include <mutex>
std::mutex m;
int main()
{
std::vector<std::thread> workers;
for (int i = 0; i < 10; ++i)
{
workers.emplace_back([i]
{
std::lock_guard<std::mutex> lock(m);
std::cout << "Hi from thread " << i << std::endl;
});
}
std::for_each(workers.begin(), workers.end(), [] (std::thread& t)
{ t.join(); });
}
Run Code Online (Sandbox Code Playgroud)
我得到输出:
Hi from thread 7
Hi from thread 1
Hi from thread 4
Hi from thread 6
Hi from thread 0
Hi from thread 5
Hi from thread 2 …Run Code Online (Sandbox Code Playgroud) 假设我有一个存储类型对象的模板T.我想传递构造函数参数以初始化数据成员.我应该使用非花括号的统一初始化或直接初始化吗?:
template<typename T>
struct X
{
template<typename... Args>
X(Args&&... args)
: t(std::forward<Args>(args)...) // ?
/* or */ : t{std::forward<Args>(args)...} // ?
private:
T t;
};
Run Code Online (Sandbox Code Playgroud)
如果我要存储的对象是a std::vector并且我选择了花括号样式(统一初始化),那么我传递的参数将被转发到vector::vector(std::initializer_list<T>)构造函数,这可能是也可能不是我想要的.
另一方面,如果我使用非大括号样式,我将失去通过其std::initializer_list构造函数向向量添加元素的能力.
当我不知道我存储的对象和将传入的参数时,我应该使用什么形式的初始化?
下面的代码是否会正确地初始化从中返回的内存malloc?
#include <cstdlib>
#include <new>
int main()
{
char* p = new (std::malloc(10)) char[10]{};
}
Run Code Online (Sandbox Code Playgroud)