假设我有foo
一个人口稠密的std::vector<double>
.
我需要对这个向量的元素进行操作.我有动力写作
for (auto it : foo){
/*ToDo - Operate on 'it'*/
}
Run Code Online (Sandbox Code Playgroud)
但似乎这不会回写,foo
因为它it
是一个值类型:已经采用了向量元素的深层副本.
我可以提供一些指导auto
来制作it
参考类型吗?然后我可以直接操作it
.
我怀疑我错过了一些简单的语法.
我很高兴auto
在我的C++程序中使用变量.我知道auto
使用模板规则声明的变量来推导变量类型,但我对数字类型的工作原理感到困惑.假设我有:
auto foo = 12;
Run Code Online (Sandbox Code Playgroud)
类型foo
可以合理地int
或甚至是unsigned char
.但是假设在我的程序中稍后我会做一些数学并给foo赋值40亿.那时,我想foo
成为一个类型unsigned int
或者也许long
.
编译器如何预测将在程序中稍后分配的值?
主要来自 Python 背景,我在使用 C++ 类型时有些挣扎。
我试图通过将不同类型作为参数的几个重载构造函数之一来初始化一个类变量。我已经读过使用auto
关键字可以用于变量的自动声明,但是在我的情况下,它不会被初始化,直到选择了构造函数。然而,编译器对不初始化不满意value
。
class Token {
public:
auto value;
Token(int ivalue) {
value = ivalue;
}
Token(float fvalue) {
value = fvalue;
}
Token(std::string svalue) {
value = svalue;
}
void printValue() {
std::cout << "The token value is: " << value << std::endl;
}
};
Run Code Online (Sandbox Code Playgroud)
在 python 中,这可能如下所示:
class Token():
def __init__(self, value):
self.value = value
def printValue(self):
print("The token value is: %s" % self.value)
Run Code Online (Sandbox Code Playgroud)
auto
在这种情况下使用关键字的正确方法是什么?我应该完全使用不同的方法吗?
假设我们有一个具有以下接口的对象:
struct Node_t {
... const std::vector< something >& getChilds() const;
} node;
Run Code Online (Sandbox Code Playgroud)
现在,我使用如下auto
变量访问该属性:
auto childs = node->getChilds();
Run Code Online (Sandbox Code Playgroud)
是什么类型的childs
?a std::vector< something >
或对一个的引用?
我现在正在学习C++,因为我需要编写一些低级程序.
当我了解"auto"关键字时,它会从C#中提醒我"var"关键字.
那么,C#"var"和C++"auto"的区别是什么?
我设法重现问题的最简单的片段如下:
#include <variant>
template <auto V>
using ic = std::integral_constant<decltype(V), V>;
enum { shake };
int milk(ic<shake>);
template <class...>
struct context {
template <auto V>
decltype(milk(ic<V>{})) get() {
return std::get<decltype(milk(ic<V>{}))>(value);
}
std::variant<int> value;
};
int main(){
context<int> c;
c.get<shake>();
}
Run Code Online (Sandbox Code Playgroud)
[clang]中有一些可疑的东西,因为它表明:
prog.cc:13:42: error: a non-type template parameter cannot have type 'auto'
return std::get<decltype(milk(ic<V>{}))>(value);
^
prog.cc:3:16: note: template parameter is declared here
template <auto V>
^
1 error generated.
Run Code Online (Sandbox Code Playgroud)
当我们更改ic
为别名类型或使用未模板化的版本时,context
所有内容都按预期工作.那真的是铿锵的错误还是我错过了一些明显的东西?
PS.在[gcc]中,一切都按预期工作......
#include <iostream>
#include <typeinfo>
int main()
{
const char a[] = "hello world";
const char * p = "hello world";
auto x = "hello world";
if (typeid(x) == typeid(a))
std::cout << "It's an array!\n";
else if (typeid(x) == typeid(p))
std::cout << "It's a pointer!\n"; // this is printed
else
std::cout << "It's Superman!\n";
}
Run Code Online (Sandbox Code Playgroud)
x
当字符串文字实际上是数组时,为什么推断为指针?
窄字符串文字的类型为"数组n
const char
"[2.14.5字符串文字[lex.string]§8]
假设我们实现了一个string
表示字符串的类.然后我们想要添加一个operator+
连接两个string
s的,并决定通过表达式模板实现它,以避免在执行时进行多次分配str1 + str2 + ... + strN
.
运算符将如下所示:
stringbuilder<string, string> operator+(const string &a, const string &b)
Run Code Online (Sandbox Code Playgroud)
stringbuilder
是一个模板类,它反过来重载operator+
并具有隐式string
转换运算符.几乎是标准的教科书练习:
template<class T, class U> class stringbuilder;
template<> class stringbuilder<string, string> {
stringbuilder(const string &a, const string &b) : a(a), b(b) {};
const string &a;
const string &b;
operator string() const;
// ...
}
// recursive case similar,
// building a stringbuilder<stringbuilder<...>, string>
Run Code Online (Sandbox Code Playgroud)
只要有人这样做,上述实现就完美无缺
string result = str1 …
Run Code Online (Sandbox Code Playgroud) // case 1
const int i = 42;
const auto &k = i;
// case 2
const int i = 42;
auto &k = i;
Run Code Online (Sandbox Code Playgroud)
在此方案中我们是否需要const
关键字auto
?毕竟,k
对自动推导类型的引用()将包括const
对象的顶层().所以我相信在两种情况下都会引用一个为constant()的整数.const
int i
k
const int &k
如果是真的,这是否意味着const auto &k = i;
如果1是由编译器代替,只是const int &k = i;
(auto
被替换为int
)?而在案例2中,auto
被替换为const int
?
int foo = 11;
int *p = &foo;
auto pp = p;
auto *ppp = p;
cout << pp << endl;
cout << ppp << endl;
Run Code Online (Sandbox Code Playgroud)
这个程序会为pp
和产生相同的输出ppp
,但为什么呢?auto
推断变量应该是int
,所以我认为声明ppp
是对的.但是pp
并且ppp
具有相同的价值......
输出:
0x61fefc
0x61fefc
Run Code Online (Sandbox Code Playgroud)