使用 std::decay 和 std::forward

Using std::decay with std::forward

template<typename T>
struct test
{
    std::string key;
    T value;
    
    template<typename U>
    using decay = typename std::decay<U>::type;

    template<typename U = decay<T>, typename US = decay<std::string>>
    test(U&& _value, US&& _key) : value(std::forward<U>(_value)), key(std::forward<US>(_key)){}
};

我几乎在每个项目中都使用这样的衰减。我想问一下,写这样的东西是否有用:

test(T&& _value, std::string&& _key) : value(std::move(_value)), key(std::move(_key)){}
test(const T& _value, std::string&& _key) : value(_value), key(std::move(_key)){}
test(T&& _value, const std::string& _key) : value(std::move(_value)), key(_key){}
test(const T& _value, const std::string& _key) : value(_value), key(_key){}

你想多了。你只需要这个:

template<typename T>
struct test
{
    std::string key;
    T value; // as a safety this could be replaced by:
    // typename std::decay<T>::type value;
    
    template<typename U, typename US>
    test(U&& _value, US&& _key)
       : value(std::forward<U>(_value))
       , key(std::forward<US>(_key))
    {}
};

这个完美的转发将确保您列出的所有构造函数都可用。

看来您不明白 std::decay 的作用,或者 when/how 无法使用它。 示例:decay<std::string> 是没有意义的,因为它只代表 std::string 类型,所以你应该只写 std::string 你不必做任何转换,因为你可以完全控制传递给 [= 的类型15=],您知道此类型不包含引用或常量,因为您已明确键入此内容。

std::decay 可用于定义您可以分配给的类型 variable/filed。它剥离引用和​​常量,C-array 转换为指针,并确保指针指向函数。请参阅 doc 示例。

您能否解释一下您计划使用模板参数的默认类型实现什么?我不明白你的意图是什么。

如果这两个值实际上都保存在您的 class 中,则比这简单得多:

test(T value, std::string key)
    : value(std::forward<T>(value)), key(std::move(key)) {}