【发布时间】:2020-11-20 18:35:52
【问题描述】:
考虑以下代码:
#include <iostream>
#include <cstdlib>
struct NonAggregate
{
// Non-aggregate due to user defined constructor
// It is also not constexpr
explicit NonAggregate(int i) : val_(i) {}
int val_;
};
template <typename T = int>
constexpr NonAggregate GetNonAggregate(NonAggregate foo)
{
return foo;
}
int main()
{
// Let us pass a random value to the constructor that can only be known at runtime just in case
std::cout << GetNonAggregate(NonAggregate(std::rand())).val_ << std::endl;
return 0;
}
此代码使用 gcc 10.2,as seen here in godbolt 编译。这段代码不能用 clang 编译:
error: constexpr function's return type 'NonAggregate' is not a literal type
但是,如果我们只是从 GetNonAggregate() constexpr 函数中删除模板:
constexpr NonAggregate GetNonAggregate(NonAggregate foo)
{
return foo;
}
然后代码无法使用 clang 和 gcc 编译。我在这里有什么遗漏吗?此代码不是有效的 C++,但代码库的某些部分依赖于 gcc 的这种行为,当我们尝试使用 clang 时突然无法编译。
我还没有用 msvc 编译器测试过这段代码,我会在测试时更新这个问题。
【问题讨论】:
-
你指的是godbolt上的msvc有什么问题?另外,如果您不关心 msvc 的作用,您可以删除最后一句。
-
@cigien 当我尝试在 Godbolt 上使用 msvc 编译代码示例时,我得到“内部服务错误”。我在 Godbolt 上从来没有遇到过这个问题,msvc 总是为我工作,所以我认为这是 Godbolt 本身的临时错误。
-
嗯,我不确定,但鉴于 clang 和 gcc 在代码上存在分歧,这可能是 msvc 编译器错误。无论如何,您应该在最后一句中提及该特定信息。
-
直到msvc版本在godbolt上编译成功我会修改那句话。
标签: c++ language-lawyer constexpr function-templates