如何在 std::forward 的构造函数中使 const 仅左值

How to make const only lvalue in a constructor with std::forward

template < typename T1, typename T2 >
MyClass(T1 && v1, T2 && v2)
    : m_v1(std::forward< T1 >(v1))
    , m_v2(std::forward< T2 >(v2))
{}

让我们有一个名为 MyClass 的 class,其构造函数如上所示。如果没有 std::forward 我们必须编写 4 个不同的构造函数:

MyClass(SomeType&& v1, SomeType&& v2);
MyClass(SomeType&& v1, const SomeType& v2);
MyClass(const SomeType& v1, SomeType&& v2);
MyClass(const SomeType& v1, const SomeType& v2);

这里我们使用const SomeType&,因为我们不想改变我们的左值。当然,我们有const_cast,但是很容易找到这样的cast。同时,我们使用 std::forward 的模板构造函数生成参数类型如下所示的构造函数:SomeType& - 没有 const 因此我们可以更改构造函数主体中的左值。

问题:正确的解法是什么?我应该添加 const (怎么做?)还是以适当的方式编写我的构造函数的主体 - 这样,它们就不会更改左值。在添加 const 的情况下,我们将得到这样的结果: const T1&& 如果我们将右值赋予构造函数,我们将无法移动它,因为它将是常量右值。我想,只有当我们给出左值时,我们才必须添加 const

我正在尝试阻止 n = 555; 此处:

#include <iostream>
#include <string>
#include <vector>
#include <utility>
#include <memory>
#include <ciso646>

class A
{
public:
    using number_t = std::int32_t;
    using string_t = std::string;

    template < typename T >
    using vector_t = std::vector < T >;

public:
    template < typename T1, typename T2, typename T3, 
        typename Dummy = std::enable_if_t < std::is_same < number_t, 
        typename std::decay < T1 > ::type > ::value > >
    A(T1 && n, T2 && s, T3 && v) :
        m_n { std::forward < T1 > (n) },
        m_s { std::forward < T2 > (s) },
        m_v { std::forward < T3 > (v) } 
    {
        n = 555;
    }

public:
    number_t              m_n;
    string_t              m_s;
    vector_t < number_t > m_v;
};

int main()
{
    A::number_t                 n { 666 };
    A::string_t                 s { "hello" };
    A::vector_t < A::number_t > v { 1, 2, 3 };

    std::cout << n << std::endl;

    A a1(n, s, v);
    A a2(1, "hello", std::vector<A::number_t>( { 4, 5, 6 } ));

    std::cout << n << std::endl;

    A a3(1, "hello", std::vector<int>( { 4, 5, 6 } ));

    return 0;
}

I’m trying to prevent n = 555; here:

您通过转发引用获取了参数。这意味着您的意图是他们推断出的行为最终取决于 caller 提供的内容。

如果调用者提供了一个非const左值,那么你得到一个非const左值。如果调用者提供了一个 const 左值,那么这就是你得到的。

由于您打算将这些参数转发到它们的最终对象中,因此您的意图是在传递右值时能够修改它们。因此你不能让他们 const.

保持原样。防止n = 555;的办法就是不写.