相关疑难解决方法(0)

在C++中创建对三元运算符结果的const引用是否安全?

这段代码中有一些非常明显的事情:

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)

c++ gcc ternary-operator c++11 clang++

23
推荐指数
1
解决办法
1341
查看次数

clang和gcc之间const参考三元运算符的地址差异

我对这里发生的事情有一个模糊的想法......它与此有关,但我想知道为什么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)

c++ gcc ternary-operator clang++

5
推荐指数
1
解决办法
142
查看次数

标签 统计

c++ ×2

clang++ ×2

gcc ×2

ternary-operator ×2

c++11 ×1