C++标准(第8.5节)说:
如果程序要求对const限定类型T的对象进行默认初始化,则T应为具有用户提供的默认构造函数的类类型.
为什么?在这种情况下,我无法想到为什么需要用户提供的构造函数.
struct B{
B():x(42){}
int doSomeStuff() const{return x;}
int x;
};
struct A{
A(){}//other than "because the standard says so", why is this line required?
B b;//not required for this example, just to illustrate
//how this situation isn't totally useless
};
int main(){
const A a;
}
Run Code Online (Sandbox Code Playgroud) 我有代码:
class A {
public:
A() = default;
private:
int i = 1;
};
int main() {
const A a;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它在g ++上编译很好(参见ideone),但在clang ++上失败并出现错误:
const类型'const A'的对象的默认初始化需要用户提供的默认构造函数
我在LLVM错误跟踪器上报告了这个问题,并使其无效.
我认为试图说服铿锵的开发者绝对毫无意义.另一方面,我没有看到这种限制的原因.
任何人都可以建议,如果C++ 11标准以某种方式暗示此代码无效?或者我应该向g ++报告错误?或许在语言规则方面有足够的自由来以多种方式处理这些代码?
以下代码与GCC编译良好:
constexpr struct {} s;
Run Code Online (Sandbox Code Playgroud)
但Clang拒绝了它,出现以下错误:
错误:没有用户提供的默认构造函数,默认初始化const类型'const struct(anonymous struct at ...)'的对象
我已经测试了我能够在https://gcc.godbolt.org/找到的所有GCC和Clang版本.每个版本的GCC都接受代码,而Clang的每个版本都拒绝它.
我想知道在这种情况下哪个编译器是正确的?
标准对此有何看法?
这是一个简短的例子,用clang重现这个"没有可行的转换"柠檬,但对编译器行为的g ++差异有效.
#include <iostream>
struct A {
int i;
};
#ifndef UNSCREW_CLANG
using cast_type = const A;
#else
using cast_type = A;
#endif
struct B {
operator cast_type () const {
return A{i};
}
int i;
};
int main () {
A a{0};
B b{1};
#ifndef CLANG_WORKAROUND
a = b;
#else
a = b.operator cast_type ();
#endif
std::cout << a.i << std::endl;
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
住在Godbolt的
g ++(4.9,5.2)默默地编译; 而clang ++(3.5,3.7)编译它
如果 …
我有下面的代码,它基本上映射std::integer_sequence<>到std::array<>编译时:
#include <iostream>
#include <utility>
#include <array>
template<int...Is>
constexpr auto make_array(const std::integer_sequence<int, Is...>& param) // this works */
// constexpr auto make_array(std::integer_sequence<int, Is...> param) // doesn't compile
{
return std::array<int, sizeof...(Is)> {Is...};
}
int main()
{
constexpr std::integer_sequence<int, 1,2,3,4> iseq;
// If I pass by value, error: the value of 'iseq' is not usable in a constant expression
constexpr auto arr = make_array(iseq);
for(auto elem: arr)
std::cout << elem << " ";
}
Run Code Online (Sandbox Code Playgroud)
只要make_array通过 …