gpt4 book ai didi

c++ - clang 和 gcc 右值引用重载的区别

转载 作者:搜寻专家 更新时间:2023-10-31 02:04:02 25 4
gpt4 key购买 nike

我正在实现一个 map 函数,它有两个重载:一个用于右值,另一个用于 const 引用:

template <class Array, class UnaryOp>
void map_inplace(UnaryOp op, Array &a) {
std::transform(a.cbegin(), a.cend(), a.begin(), op);
}

template <class Array, class UnaryOp>
auto map(UnaryOp op, Array &&a) {
map_inplace(op, a);
return a;
}

template <class Array, class UnaryOp>
auto map(UnaryOp op, const Array &a) {
Array res(a);
map_inplace(op, res);
return res;
}

我有以下测试:

TEST_CASE("map") {
const std::vector v{1., 2., 3.};

// I do expect the const reference overload to be called
REQUIRE(almost_equal(map(std::negate<>(), v), {-1., -2., -3.}));

// Check const vector is not modified
REQUIRE(v == std::vector{1., 2., 3.});
}

用 Clang 运行它测试通过:

passed: almost_equal(map(std::negate<>(), v), {-1., -2., -3.}) for: true

passed: v == std::vector{1., 2., 3.} for: { 1.0, 2.0, 3.0 } == { 1.0, 2.0, 3.0 }

Passed 1 test case with 2 assertions.

但它在 GCC 中失败了:

passed: almost_equal(map(std::negate<>(), v), {-1., -2., -3.}) for: true

failed: v == std::vector{1., 2., 3.} for: { -1.0, -2.0, -3.0 } == { 1.0, 2.0, 3.0 }

Failed 1 test case, failed 1 assertion.

因此 GCC 正在调用右值引用重载并正在修改 const 定义的 vector 。

GCC 版本是:

gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0

Clang 版本是:

clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)

编辑:

所以我尝试了更多测试,GCC 失败了:

TEST_CASE("map") {
const std::vector v{1., 2., 3.};
REQUIRE((map(std::negate<>(), v) == std::vector{-1., -2., -3.}));
REQUIRE(v == std::vector{1., 2., 3.});
}

但是如果我添加模板类型参数:

TEST_CASE("map") {
const std::vector<double> v{1., 2., 3.};
REQUIRE((map(std::negate<>(), v) == std::vector<double>{-1., -2., -3.}));
REQUIRE(v == std::vector<double>{1., 2., 3.});
}

然后就可以了!

最佳答案

演示此问题的最小示例:

#include <vector>
#include <type_traits>

const ::std::vector<double> v1{1., 2., 3.};
const ::std::vector v{1., 2., 3.};
static_assert(::std::is_same_v<decltype(v1), decltype(v)>); // error on gcc

online compiler

Bug 80990 - cv-qualifiers ignored in variable definition using class template argument deduction

关于c++ - clang 和 gcc 右值引用重载的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54269248/

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