可能这可能是一个非常基本的问题,但仍然想了解一些基本概念......
为什么我们将变量定义为 const ?- 在整个程序中保持该特定变量的值恒定。
但是,当我遇到构造函数的初始化列表时,它允许在对象构造期间为 const 变量赋值(例如,我尝试了下面的程序),我对 const 关键字本身的基本概念感到困惑。有人可以澄清这一点吗?
如果允许在对象构造期间更改 const 变量,那么以下程序中 const 变量的用途是什么?我们有针对这些行为的实时场景吗?如果是这样,您能给出一些场景吗?
#include<iostream>
using namespace std;
class Test {
const int t;
public:
Test(int t):t(t) {} //Initializer list must be used
int getT() { return t; }
};
int main() {
Test t1(10);
cout<<t1.getT();
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我需要详细说明以下类的构造函数:
class Foo {
public:
const std::vector<Bar> bars;
Foo(int num_bars, ...);
}
Run Code Online (Sandbox Code Playgroud)
为了讨论的方便,假设额外的参数是 allconst Bar&或 just Bar。
我需要使用 va_list 中的条来初始化 v 的构造。我怎样才能做到这一点?
我知道许多人使用私有成员变量名称的前缀或后缀。对于那些不这样做,但只使用名称的人 - 如果您想要具有相同名称的构造函数参数,如何初始化它们?
为什么 C++ 选择原始类型重载匹配而不是“更好”的匹配初始值设定项列表?
#include <vector>
void foo([[maybe_unused]] int i) {}
void foo([[maybe_unused]] const std::vector<int>& v) {}
int main() {
foo(0);
foo({1,2,3});
foo({0}); // calls foo(int) and issues a warning,
// rather than what seems like the "better"
// match foo(vector).. why?
}
Run Code Online (Sandbox Code Playgroud)
<source>:10:9: warning: braces around scalar initializer [-Wbraced-scalar-init]
foo({0}); // calls foo(int) and issues a warning,
^~~
Run Code Online (Sandbox Code Playgroud)
也许是“令人惊讶”的结果,因为编译器选择了随后发出诊断的选项?
使用 Clang 14
c++ overloading initializer-list language-lawyer overload-resolution
我知道函数可以通过template参数传递,我可以像这样传递类Constructor.
更新:
我想要这样做的全部原因是,我可以在内存池中选择构造函数,并且在我想要分配的类中没有任何代码更改(在本例中class A)
class A
{
public:
A(){n=0;}
explicit A(int i){n=i;}
private:
int n;
};
class MemoryPool
{
public:
void* normalMalloc(size_t size);
template<class T,class Constructor>
T* classMalloc();
};
template<class T,class Constructor>
T* MemoryPool::classMalloc()
{
T* p = (T*)normalMalloc(sizeof(T));
new (p) Constructor; // choose constructor
return p;
}
MemoryPool pool;
pool.classMalloc<A,A()>(); //get default class
pool.classMalloc<A,A(1)>();
Run Code Online (Sandbox Code Playgroud) iostream和其他流类实际上不是类,但typedefs,对吗?
这是问题所在,我试图istream在初始化列表中初始化一个对象,但不幸的是我收到了一个错误,代码如下:
class A
{
public:
A(istream &is=cin): ais(is)
{}
private:
istream ais;
};
Run Code Online (Sandbox Code Playgroud)
无法用g ++编译,错误:
synthesized method ‘std::basic_istream<char, std::char_traits<char> >::basic_istream(const std::basic_istream<char, std::char_traits<char> >&)’ first required here
Run Code Online (Sandbox Code Playgroud)
我搜索了SO,发现了,iostream cannot be assigned or copy.但为什么我不能在初始化列表中初始化它?
我想,初始化列表会调用对象的构造函数/ copy-constructor,对吧?
是否可以使用C++ 11 使用构造函数initializer_list组装递归定义的类Foo,如下所示constexpr:
template <size_t N>
struct Foo {
constexpr Foo(int x, Foo<N-1> f) : x(x), xs(xs) {}
int x;
Foo<N-1> xs;
};
template <> struct Foo<0> {};
Run Code Online (Sandbox Code Playgroud)
我可以初始化一个Foo<3>使用:
int main(int argc, char *argv[])
{
Foo<3> a = Foo<3>(1,Foo<2>(2,Foo<1>(3,Foo<0>())));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
最好使用Foo <3> a = {1,2,3}.如果有一个constexpr tail功能,initializer_list我认为它应该工作.
c++ recursive-datastructures initializer-list constexpr c++11
我正在尝试使用初始化列表将关键字列表传递给tokenizer进行注册.但它在Visual Studio 2013中不起作用.它适用于ideone.com上的gcc.有没有办法在VS中使用这个或类似的语法?
struct Keyword
{
const char* name;
int id;
};
void AddKeywords(int group, std::initializer_list<Keyword>& lis) {}
// usage
AddKeywords(ITEM_TYPE, {
{ "weapon", IT_WEAPON },
{ "armor", IT_ARMOR }
});
Run Code Online (Sandbox Code Playgroud)
完整错误:
item.cpp(810): error C2664: 'void AddKeywords(int,std::initializer_list<Keyword> &)' : cannot convert argument 2 from 'initializer-list' to 'std::initializer_list<Keyword> &'
Run Code Online (Sandbox Code Playgroud) 这是我练习册上的一个问题:
如果我们写
int a[][3]={{0},{1},{2}};,元素的值a[1][2]将是____.
关键是它的价值无法得知.由于语句不被授予在函数外部写入,因此矩阵不应简单地视为全局变量,它将所有元素初始化为0.但是,我认为初始化{{0},{1},{2}}器相当于{{0,0,0},{1,0,0},{2,0,0}},所以a[1][2]应该是0.谁错了,关键还是我?
PS:我写了这段代码:
#include <stdio.h>
int main()
{
int a[][3]={{0},{1},{2}};
printf("%d",a[1][2]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它的输出正好是0.
我有这个代码:
#include <iostream>
#include <vector>
template<typename T>
void print_size(std::vector<T> a)
{
std::cout << a.size() << '\n';
}
int main()
{
std::vector<int> v {1, 2, 3};
print_size(v);
auto w = {1, 2, 3};
// print_size(w); // error: no matching function for call to 'print_size'
// candidate template ignored: could not match 'vector' against 'initializer_list'
}
Run Code Online (Sandbox Code Playgroud)
...编译和运行没有任何问题.但是,如果我启用注释掉的行,则会产生错误no matching function for call to 'print_size'.
我想知道在C++ 11及更高版本中编写此代码的正确方法是什么.
initializer-list ×10
c++ ×9
c++11 ×3
constructor ×3
auto ×1
c ×1
constants ×1
constexpr ×1
iostream ×1
overloading ×1
scope ×1
templates ×1
vector ×1