我正在使用以下代码。
#include <iostream>
#include <span>
#include <vector>
std::vector v{1,2,3,4,5,6};
template <template <typename, std::size_t> class S>
S<int, std::dynamic_extent> GetSpan()
{
return v;
}
int main()
{
auto x = GetSpan<std::span>();
return 0;
}
这是accepted由 GCC 和 Clang 共同编写。但是,如果我在函数 GetSpan()
中将 std::vector
设为本地,i。
template <template <typename, std::size_t> class S>
S<int, std::dynamic_extent> GetSpan()
{
std::vector v{1,2,3,4,5,6};
return v;
}
叮当依然accepts代码,但 gcc 拒绝它。 哪个编译器在这里,为什么?
最佳答案
您的代码无法在 C++23 模式下编译。这是因为返回变量时进行了简化的隐式移动。 (参见:cpppreference、P2266R3)
std::vector v{1,2,3,4,5,6};
return v;
与
相同 std::vector v{1,2,3,4,5,6};
return std::move(v);
...还有一个std::span<int>
无法从右值 vector 构造。
之前的行为是尝试移动,如果该移动不可能,则会进行复制。
看起来 gcc 即使在 C++20 模式下也会进行简化的移动。
其中之一可以修复它:
return (std::vector<int>&) v;
return static_cast<std::vector<int>&>(v); // (This seems like the recommended solution)
return static_cast<decltype((v))>(v);
return static_cast<decltype(v)&>(v);
return std::identity{}(v);
// These two may have slightly different behaviour depending on
// the constructors of the return type, but work here
return { v };
return S<int, std::dynamic_extent>(v);
关于c++ - 在模板化函数中将 std::vector 设置为本地会导致编译失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76737907/