具有模板化构造函数以及复制和移动构造函数的类

2023-12-11

这个问题是这个问题的后续问题:模板类的模板构造函数的显式模板专业化另一个问题中给出的答案当然是正确的,但事实证明我并没有完全问我想问的问题 - 所以这是一个新问题:

考虑以下代码:

template<typename First, typename ... Rest> class var {
    public:

    var() {
        std::cout << "default" << std::endl;
    }

    var(const var& v) {
        std::cout << "copy" << std::endl;
    }

    var(var&& v) {
        std::cout << "move" << std::endl;
    }

    template<typename T>
    var(const T& t) {
        std::cout << "general lvalue" << std::endl;
    }


    template<typename T>
    var(T&& t) {
        std::cout << "general rvalue" << std::endl;
    }

};


int main()
{
    var<int> i0; // expect 'default' -> get 'default'

    var<int> i1(i0); // expect 'copy' -> get 'general rvalue'
    var<int> i2(std::move(i0)); // expect 'move' -> get 'move'

    std::string s("Hello");
    var<int> i3(s); // expect 'general lvalue' -> get 'general rvalue'
    var<int> i4(std::move(s)); // expect 'general rvalue' -> get 'general rvalue'
}

我在主函数中写下了我期望并希望调用哪些构造函数以及实际调用了哪些构造函数。这是我的问题:

1)你能解释一下为什么程序的行为不符合我的预期吗?

2)如何让程序在获取 var 时调用 var 的复制和移动构造函数,否则调用模板化构造函数?

3)最后,我试图将两个模板化构造函数放入一个处理左值和右值的构造函数中,并使用 std::forward 将它们转发到另一个函数 - 这看起来怎么样?


1)你能解释一下为什么程序的行为不符合我的预期吗?

在这一行:

var<int> i1(i0); // expect 'copy' -> get 'general rvalue'

The var(T&&)构造函数实例化为T替换为var<int>&,即生成具有此签名的构造函数:

var(var&);

该构造函数比隐式复制构造函数更匹配var(const var&)因为i0是非常量。

同样对于:

var<int> i3(s); // expect 'general lvalue' -> get 'general rvalue'

s是非常量,所以var(T&&)构造函数实例化为T替换为std::string&,生成一个带有签名的构造函数:

var(std::string&);

对于非常量参数,构造函数比其他构造函数模板更匹配,它会生成:

var(const std::string&);

您需要意识到var(T&&)构造函数不是“通用右值”构造函数,因为T&&可以匹配任何类型包括左值.

See C++11 中的通用引用更多细节。

2)如何让程序在获取 var 时调用 var 的复制和移动构造函数,否则调用模板化构造函数?

限制模板,使其不接受any type.

template<typename T>
  using Is_a_var = std::is_same<typename std::decay<T>::type, var>;

template<typename T>
  using Enable_if_not_a_var = typename std::enable_if<!Is_a_var<T>::value>::type;

template<typename T, typename Constraint = Enable_if_not_a_var<T>>
var(T&& t) {
    std::cout << "general value" << std::endl;
}

我还会添加默认的复制/移动构造函数,以便读者清楚地了解您想要它们:

var(const var&) = default;
var(var&&) = default;

3)最后,我试图将两个模板化构造函数放入一个处理左值和右值的构造函数中,并使用 std::forward 将它们转发到另一个函数 - 这看起来怎么样?

不。这var(T&&)构造函数已经接受两个右值and左值。

Use std:forward<T>(t)将参数转发给其他函数:

template<typename T, typename Constraint = Enable_if_not_a_var<T>>
var(T&& t) : m_something(std::forward<T>(t)) {
    std::cout << "general value" << std::endl;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

具有模板化构造函数以及复制和移动构造函数的类 的相关文章

随机推荐

  • 向小部件添加标签

    我正在尝试使用 Qt 将标签添加到主窗口 这是一段代码 int main int argc char argv QApplication app argc argv QWidget Main Window QPixmap Image Ima
  • JavaScript reload() 是否会停止处理页面的其余部分?

    在我的测试中 JavaScriptreload 函数似乎阻止了它后面的代码执行 但任何人都可以确认这是真的100 的时间 假设用户启用了 JavaScript 并且没有花哨的技巧 That is
  • 对于包含空格的文件路径,FFMPEG 命令失败

    我正在执行以下操作ffmpeg用于修剪视频的命令 我遇到的问题是 如果文件路径包含空格 则命令失败 我尝试了多种方法来处理空格 但除了将文件移动到没有空间的路径然后执行命令之外 没有一种方法有效以新文件路径作为源 下面是命令 execFFm
  • 正则表达式删除所有后面不跟数字的句点

    I have str replace 0 9 g 但它会删除除句点和句点后面的数字之外的所有内容 例如 3 14 变为 1 我想要的是 3 14 gt 3 14 hello world gt helloworld hi gt hi hi 2
  • MongoDB ObjectID 为何是 12 字节?

    据我所知 MongoDB中的字符串以UTF 8存储 因此每个字符在1到4个字节之间 MongoDB 文档对 ObjectID 有如下描述 返回新的 ObjectId 值 12 字节的 ObjectId 值包括 一个 4 字节值 表示自 Un
  • 处理播放中动态创建的文件 2

    我编写了一个小应用程序 可以使用 play 2 0 创建可下载的 pdf 文件 我想为公众服务 在我的开发环境中 我创建了一个文件夹 assets 文件夹 一切都很好 现在 当切换到生产环境时 我发现 play 总是在我背后部署这些文件 我
  • MySQL 上 Django 中的列数据太长

    对于模型中声明为的列 我收到此错误TextField数据库中是一个 LONGTEXT 而我尝试插入的值只有 3KB 长 AFAIK LONGTEXT 理论限制是 2GB 所以我不知道为什么有这个限制或如何绕过它 有任何想法吗 我得到的具体异
  • ngx-capture :无法捕获屏幕捕获区域内的

    我无法捕捉 img 在屏幕捕获区域内 我想要一个定义的部分 其中包含要捕获的图像和内容 我们怎样才能做到这一点 帮助 Visit https stackblitz com edit ngx capture div angular wnkjw
  • 如何存储自定义对象数组(目标)

    如何存储在 NSUserDefaults 中创建的 Goal 类型的对象数组 快速 这是代码 func saveGoalList newGoalList Goal let updatedGoalList newGoalList NSUser
  • 在 Xcode 中打开非 Xcode 项目

    现在我正在开发一个使用 Markdown 的静态网站 我不想在 SublimeText 中编辑文件 而是想在 Xcode 中编辑它们 我可以在 Xcode 中打开各个文件 但我想打开整个静态站点目录并受益于使用文件导航器窗格和其他 Xcod
  • PHP:通过 ID 将 html 内容附加(添加)到现有元素

    我需要使用 PHP 按 ID 搜索元素 然后向其附加 html 内容 这看起来很简单 但我是 php 新手 找不到合适的函数来执行此操作 html file get contents http example com doc new DOM
  • Matlab中不同大小的矩阵数组

    是否可以在 Matlab 中创建具有不同大小的矩阵数组 例如 Array Mat 1 zeros 3 Array Mat 2 zeros 4 这会产生错误 那么我怎样才能制作矩阵数组呢 您可以使用细胞 gt gt a 1 1 2 3 4 a
  • Firebase数据库持久存储[关闭]

    Closed 这个问题需要细节或清晰度 目前不接受答案 只是想知道是否Firebase 持久性存储当它缓存到设备上的磁盘时会被加密 我们希望在特定路径上利用 Firebase 同步来向用户推送更快的更新 当您执行以下操作时 Firebase
  • Angular2 *ngFor:“无法读取未定义的属性‘0’”

    我尝试从 JSON 文件获取数据来构建表单 这是我的模板的一部分 div class form group div
  • std::vector 可以利用小缓冲区优化吗?

    今天我和同事想知道是否可以实现 std vector 来利用小缓冲区优化 通过查看 C 11 草案 我在 23 3 1p8 读到 对于除数组之外的标准容器类型的容器 a 和 b 表达式 a swap b 应交换 a 和 b 的值 而不对各个
  • 从 Rust 中的 RefCell>> 获取引用

    我在从 RefCell gt 获取引用时遇到问题 有什么建议吗 struct Node
  • 为什么 var foo = null 编译

    我从 Kotlin 开始并试图理解一些东西 var foo String null未按预期编译 var foo String null应该是正确的语法并按预期进行编译 那么为什么var foo null编译 的类型foo在这种情况下将被推断
  • C++ 中空结构的用法

    在我正在阅读的一些代码中 我发现空结构的用法如下 struct input iterator tag struct bidirectional iterator tag struct random access iterator tag 所
  • 使用 AHK 关闭 Visual Studio 中的弹出对话框

    我重新映射了几个键 效果很好 然而 我在尝试摆脱视觉工作室中的弹出对话框时遇到了困难 这是我尝试过的 WinWaitActive Microsoft Visual Studio If WinActive Microsoft Visual S
  • 具有模板化构造函数以及复制和移动构造函数的类

    这个问题是这个问题的后续问题 模板类的模板构造函数的显式模板专业化另一个问题中给出的答案当然是正确的 但事实证明我并没有完全问我想问的问题 所以这是一个新问题 考虑以下代码 template