C++ 大括号初始化可防止非常量使用临时

C++ 大括号初始化可防止非常量使用临时,c++,temporary,list-initialization,C++,Temporary,List Initialization,我想创建常量对象的临时副本,并以非常量方式使用它: struct S { S& f() { return *this; } }; int main() { const S a{}; S{a}.f(); // Error on this line return 0; } 使用msvc(Visual Studio 2017,C++14),我得到以下错误: 错误C2662'S&S::f(void)':无法将'this'指针从'const S'转换为'S&'

我想创建常量对象的临时副本,并以非常量方式使用它:

struct S {
    S& f() { return *this; }
};

int main() {
    const S a{};
    S{a}.f(); // Error on this line
    return 0;
}
使用msvc(Visual Studio 2017,C++14),我得到以下错误:

错误C2662'S&S::f(void)':无法将'this'指针从'const S'转换为'S&'

如果我将大括号初始化更改为经典初始化,它将起作用:

S{a}.f(); // Does not work
S(a).f(); // Works

这两个变体在gcc中都编译得很好。我是遗漏了什么还是这是一个编译器错误?

它看起来像是一个编译器错误,或者是一个奇怪的优化的结果,因为原始代码的这种变化只会使带有副作用的CTOR和dtor使用MSVC编译得很好:

#include <iostream>

struct S {
    S(const S& other) {
        std::cout << "Copy ctor " << &other << " -> " << this << std::endl;
    }
    S() {
        std::cout << "Default ctor " << this << std::endl;
    }
    ~S() {
        std::cout << "Dtor " << this << std::endl;
    }
    S& f() { return *this; }
};

int main() {
    const S a{};
    std::cout << &a << std::endl;
    S{a}.f();
    return 0;
}

看起来像是MSVC的另一个bug

S{a}
被推断为
const-struct S
,这就是bug

#include <string>
#include <iostream>

template < class T >
std::string type_name()
{
    std::string p = __FUNCSIG__;
    return p.substr( 106, p.length() - 106 - 7 );
}


struct S {
    S& f() { return *this; }
};

int main() {
    const S a{};
    //S{a}.f(); // Error on this line
    std::cout << type_name<decltype(S{a})>() << std::endl;
    return 0;
}

你使用C++的哪一个版本来编译你的代码?假设C++11fyi g++5.1.0编译OK,这是为您准备的:@Elyasin我以C++14I的身份编译此文件,如果您能提供链接或为什么这是一个错误,我将不胜感激。@Elyasin这是一个错误,因为不应该有任何类型推断。直接列表初始化不推断类型。
const struct S