gpt4 book ai didi

c++ - Clang 3.7.0 提示类不是文字,因为它不是聚合并且没有 constexpr 构造函数

转载 作者:太空狗 更新时间:2023-10-29 23:49:31 26 4
gpt4 key购买 nike

以下代码在 GCC (4.9.3) 和 VC++ (19.00.23506) 中编译良好,但在 Clang (3.7.0) 中会出现这些错误。

error: constexpr function's return type 'Foo' is not a literal type

note: 'Foo' is not literal because it is not an aggregate and has no constexpr constructors other than copy or move constructors

代码:

#include <iostream>
#include <vector>

struct Foo
{
std::vector<int> m_vec;
Foo(const int *foo, std::size_t size=0):m_vec(foo, foo+size)
{;}
//Foo(const std::initializer_list<int> &init):m_vec{init}
//{;}
};


template <std::size_t N>
constexpr Foo make_fooArray(const int (&a)[N]) noexcept
{
return {a,N};
}


int main()
{
Foo f{ make_fooArray({1,2,3}) };

for (auto i : f.m_vec)
std::cout<< i <<" ";
std::cout<<std::endl;
}

在 rextester 上运行的代码:

GCC & VC

Clang

您能否澄清这是编译器错误还是我遗漏了什么? C++11 标准怎么说?


这是另一种情况,它可以在 GCC 和 VC 中编译,但不能在 Clang 中编译。

#include <iostream>

template <typename T, std::size_t N>
constexpr std::size_t sizeOf_fooArray(const T (&)[N]) noexcept
{
return N;
}

int main()
{
std::cout<< sizeOf_fooArray({16,20,53,87,54,7}) <<std::endl;
}

但是,如果您为 int[] 设置别名并显式使用它来指定 initializer_list 的类型,则它适用于所有编译器。

#include <iostream>

template <typename T, std::size_t N>
constexpr std::size_t sizeOf_fooArray(const T (&)[N]) noexcept
{
return N;
}

using intArray = int[]; //Added

int main()
{
std::cout<< sizeOf_fooArray(intArray{16,20,53,87,54,7}) <<std::endl;
}

最佳答案

所有编译器都是正确的。

对于函数模板,一般来说,一个实例化可能满足 constexpr 的要求。功能,但另一个没有。通常,这意味着 constexpr对于那些不符合要求的实例,有效地被忽略。示例:

template <typename T> constexpr T f(T v) { return v; }

f<int>f<std::string>实例化是有效的,但是 f<std::string>不能在常量表达式中调用。

但是,作为该规则的一个异常(exception),如果没有任何可能的模板参数可以导致实例化满足 constexpr 的通常要求|功能,程序格式错误,不需要诊断。这意味着编译器可以完全忽略此规则,但同样可以将代码诊断为 fatal error 。

一般来说,不可能可靠地检测到违反此规则的情况,这就是不需要诊断的原因。一些编译器比其他编译器更努力地提供一些诊断。

所有这些都在 [dcl.constexpr]p6 中的标准中进行了描述:

If the instantiated template specialization of a constexpr function template or member function of a class template would fail to satisfy the requirements for a constexpr function or constexpr constructor, that specialization is still a constexpr function or constexpr constructor, even though a call to such a function cannot appear in a constant expression. If no specialization of the template would satisfy the requirements for a constexpr function or constexpr constructor when considered as a non-template function or constructor, the template is ill-formed; no diagnostic required.

关于c++ - Clang 3.7.0 提示类不是文字,因为它不是聚合并且没有 constexpr 构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40548269/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com