如果一个不知道其参数类型的人怎么能默认一个特殊的成员函数?

如何解决如果一个不知道其参数类型的人怎么能默认一个特殊的成员函数?

| 考虑这种情况:
template<typename T>
struct A {
  A(A ???&) = default;
  A(A&&) { /* ... */ }
  T t;
};
我显式声明了一个move构造函数,因此,如果我想拥有一个未删除的复制构造函数,则需要显式声明一个复制构造函数。如果要对它进行“ 1”设置,如何找到正确的参数类型?
A(A const&) = default; // or
A(A &) = default; // ?
我也对您是否遇到过这样的情况真正在实际程序中弹出的情况感兴趣。规格说   明确默认的功能应...         具有相同的声明函数类型(除了可能使引用限定符不同以及在   如果是复制构造函数或复制赋值运算符,则参数类型可以是\“对非常量T的引用”,其中T是成员函数的类的名称),就好像它是隐式声明的一样,    如果隐式声明的副本构造函数的类型为
A &
,我想让我的副本构造函数的参数类型为
A &
显式默认。但是,如果隐式声明的副本构造函数的参数类型为
A const&
,则我不想让我的默认默认副本构造函数的参数类型为
A &
,因为这将禁止从const左值进行复制。 我不能同时声明两个版本,因为在隐式声明的函数具有参数类型“ 3”而我的显式默认声明具有参数类型“ 5”的情况下,这将违反上述规则。据我所知,仅当隐式声明为
A const&
且显式声明为
A &
时才允许有区别。 编辑:事实上,规范说,甚至   如果某个函数的第一个十进制显式默认为   感叹,...         对于复制构造函数,移动构造函数,复制赋值运算符或移动赋值运算符,其参数类型应与隐式声明的参数类型相同。    因此,我需要定义这些类之外的类(我认为这没有什么坏处,因为据我所知,唯一的区别是该函数将变得不平凡,无论如何在这些情况下都是如此)
template<typename T>
struct A {
  A(A &);
  A(A const&);
  A(A&&) { /* ... */ }
  T t;
};

// valid!?
template<typename T> A<T>::A(A const&) = default;
template<typename T> A<T>::A(A &) = default;
好吧,我发现如果显式声明的函数为
A const&
,则无效,而隐式声明为
A &
:   由用户提供的显式默认函数(即在其首次声明后显式默认)在显式默认的位置定义;如果将此类函数隐式定义为Delete,则程序格式错误。 这与GCC所做的匹配。现在,我如何才能实现与隐式声明的构造函数的类型匹配的最初目标?     

解决方法

        在我看来,您将需要某种类型的演绎(概念?)。 除非成员之一要求将其写为“ 15”,否则编译器通常将使用“ 14”版本。因此,我们可以包装一些小模板黑客,以检查每个成员具有哪个版本的副本构造函数。 最新 请在ideone上进行咨询,或在代码段之后按Clang阅读错误。
#include <memory>
#include <type_traits>

template <bool Value,typename C>
struct CopyConstructorImpl { typedef C const& type; };

template <typename C>
struct CopyConstructorImpl<false,C> { typedef C& type; };

template <typename C,typename T>
struct CopyConstructor {
  typedef typename CopyConstructorImpl<std::is_constructible<T,T const&>::value,C>::type type;
};

// Usage
template <typename T>
struct Copyable {
  typedef typename CopyConstructor<Copyable<T>,T>::type CopyType;

  Copyable(): t() {}

  Copyable(CopyType) = default;

  T t;
};

int main() {
  {
    typedef Copyable<std::auto_ptr<int>> C;
    C a; C const b;
    C c(a); (void)c;
    C d(b); (void)d;  // 32
  }
  {
    typedef Copyable<int> C;
    C a; C const b;
    C c(a); (void)c;
    C d(b); (void)d;
  }
}
这使:
6167745.cpp:32:11: error: no matching constructor for initialization of \'C\' (aka \'Copyable<std::auto_ptr<int> >\')
        C d(b); (void)d;
          ^ ~
6167745.cpp:22:7: note: candidate constructor not viable: 1st argument (\'const C\' (aka \'const Copyable<std::auto_ptr<int> >\')) would lose const qualifier
      Copyable(CopyType) = default;
      ^
6167745.cpp:20:7: note: candidate constructor not viable: requires 0 arguments,but 1 was provided
      Copyable(): t() {}
      ^
1 error generated.
版前 这是我能想到的最好的方法:
#include <memory>
#include <type_traits>

// Usage
template <typename T>
struct Copyable
{
  static bool constexpr CopyByConstRef = std::is_constructible<T,T const&>::value;
  static bool constexpr CopyByRef = !CopyByConstRef && std::is_constructible<T,T&>::value;

  Copyable(): t() {}

  Copyable(Copyable& rhs,typename std::enable_if<CopyByRef>::type* = 0): t(rhs.t) {}
  Copyable(Copyable const& rhs,typename std::enable_if<CopyByConstRef>::type* = 0): t(rhs.t) {}

  T t;
};

int main() {
  {
    typedef Copyable<std::auto_ptr<int>> C; // 21
    C a; C const b;                         // 22
    C c(a); (void)c;                        // 23
    C d(b); (void)d;                        // 24
  }
  {
    typedef Copyable<int> C;                // 27
    C a; C const b;                         // 28
    C c(a); (void)c;                        // 29
    C d(b); (void)d;                        // 30
  }
}
几乎可以正常工作...除了在构建“ a”时出现一些错误。
6167745.cpp:14:78: error: no type named \'type\' in \'std::enable_if<false,void>\'
      Copyable(Copyable const& rhs,typename std::enable_if<CopyByConstRef>::type* = 0): t(rhs.t) {}
                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
6167745.cpp:22:11: note: in instantiation of template class \'Copyable<std::auto_ptr<int> >\' requested here
        C a; C const b;
          ^
和:
6167745.cpp:13:67: error: no type named \'type\' in \'std::enable_if<false,void>\'
      Copyable(Copyable& rhs,typename std::enable_if<CopyByRef>::type* = 0): t(rhs.t) {}
                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
6167745.cpp:28:11: note: in instantiation of template class \'Copyable<int>\' requested here
        C a; C const b;
          ^
两者都是由于相同的原因发生的,我不明白为什么。似乎即使我有默认构造函数,编译器仍会尝试实现所有构造函数。我本以为SFINAE将适用,但似乎并非如此。 但是,正确检测到错误行24:
6167745.cpp:24:11: error: no matching constructor for initialization of \'C\' (aka \'Copyable<std::auto_ptr<int> >\')
        C d(b); (void)d;
          ^ ~
6167745.cpp:13:7: note: candidate constructor not viable: 1st argument (\'const C\' (aka \'const Copyable<std::auto_ptr<int> >\')) would lose const qualifier
      Copyable(Copyable& rhs,typename std::enable_if<CopyByRef>::type* = 0): t(rhs.t) {}
      ^
6167745.cpp:11:7: note: candidate constructor not viable: requires 0 arguments,but 1 was provided
      Copyable(): t() {}
      ^
在这里,我们可以看到CopyByConstRef已从重载集中正确退出,这要归功于SFINAE。     ,        我想我看不到问题了……与实现复制构造函数的常见情况有什么不同? 如果您的副本构造函数不会修改参数(并且隐式定义的副本构造函数不会这样做),则应将参数作为常量引用传递。我所知道的唯一一个不使用常量引用作为参数的副本构造函数的用例是,在C ++ 03中,当您想要实现移动la
std::auto_ptr
时,这通常是个坏主意。在C ++ 0x中,移动将像使用move构造函数一样实现。     ,        我从未见过隐式副本构造函数为
A&
的情况-在任何情况下都应以you24ѭ做为好。     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-