这段代码中有一些非常明显的事情:
float a = 1.;
const float & x = true ? a : 2.; // Note: `2.` is a double
a = 4.;
std::cout << a << ", " << x;
Run Code Online (Sandbox Code Playgroud)
clang和gcc输出:
4, 1
Run Code Online (Sandbox Code Playgroud)
人们会天真地期望两次打印相同的值,但事实并非如此.这里的问题与参考无关.有一些有趣的规则决定了它的类型? :.如果两个参数的类型不同并且可以进行转换,则它们将使用临时的.该引用将指向临时的? :.
上面的示例编译得很好,在编译时可能会也可能不会发出警告,-Wall具体取决于编译器的版本.
这是一个例子,说明在看似合法的代码中出错这么容易:
template<class Iterator, class T>
const T & min(const Iterator & iter, const T & b)
{
return *iter < b ? *iter : b;
}
int main()
{
// Try to remove the const …Run Code Online (Sandbox Code Playgroud) 我对这里发生的事情有一个模糊的想法......它与此有关,但我想知道为什么clang ++和g ++处理这个问题的方式不同.这里的未定义行为在哪里?注意:这与模板无关 - 我只是使用它们来使示例更紧凑.这都是关于它的类型whatever.
#include <iostream>
#include <vector>
template <typename T>
void test()
{
T whatever = 'c';
const char a = 'a';
std::cout << "begin: " << (void*)&a << std::endl;
const char & me = (true ? a : whatever);
std::cout << "ref: " << (void*)&me << std::endl;
}
int main(int argc, char**argv)
{
test<const char>();
test<char>();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
gcc输出(测试高达4.9.3):
begin: 0x7fffe504201f
ref: 0x7fffe504201f
begin: 0x7fffe504201e
ref: 0x7fffe504201f
Run Code Online (Sandbox Code Playgroud)
clang 3.7.0输出:
begin: 0x7ffed7b6bb97
ref: …Run Code Online (Sandbox Code Playgroud)