复制构造函数与使用std::any的构造函数之间的冲突。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了复制构造函数与使用std::any的构造函数之间的冲突。相关的知识,希望对你有一定的参考价值。

我正在测试c++17的std:any功能,它似乎解决了我项目中的许多类型问题。尽管如此,我还是走到了一个死胡同......。

看看这个例子(工作)代码。

#include <any>
#include <string>
#include <iostream>
#include <vector>

class Test

public:
    Test(const Test &o) : name(o.name), data(o.data)  std::cout << "copy constructor" << std::endl; ;
    Test(std::string name, const char *data) : name(name), data(data)  std::cout << "string-constchar constructor" << std::endl; 
    Test(std::string name, std::any data) : name(name), data(data)  std::cout << "string-any constructor" << std::endl; 
    explicit Test(std::any data) : data(data)  std::cout << "any constructor" << std::endl; 

    std::string name;
    std::any data;
;

int main()

    Test t1("test", "test 2");
    Test t2("test", 57);
    Test t3 = t1;
    Test t4(97);
    // std::vector<Test> vt;
    // vt.push_back(t3);

    return 0;

如果我们在g++9下编译并运行这段代码,我们会发现可能是我们很多人所期望的。

string-constchar constructor
string-any constructor
copy constructor
any constructor

有趣的是,编译器是如何完美地辨别出 std::anyconst char* 并调用正确的构造函数。

然而,它带来了许多处理复制构造函数的问题。举个例子,如果 explicit 关键字从构造函数中删除,并使用param std::any,它会立即与复制构造函数发生冲突,编译器(clang-9 g++9)会报告一个编译错误。

同样的情况也会发生在2个注释行(向量行)没有注释的时候。push_backemplace_back可能会在某个时候调用copy构造函数,这又会触发这个与copy构造函数之间冲突有关的编译错误。

我很不明白为什么编译器不能处理复制构造函数的情况(但其他的却没有任何问题)。有什么办法可以解决这个问题吗?有什么可能的解决方法吗?

谢谢你!我正在测试c++17。

答案

当你有这样的东西。

struct X 
    X();
    X(std::any);
;

X a;
X b = a;

当我们试图弄清楚如何处理复制... b我们有复制构造函数,但我们也有 X(std::any) 可行,如果 X 是可复制的,为了检查这一点,我们必须递归检查是否有 X 是可以用一个 X 这又让我们陷入 X(std::any) 构造函数。

现在,有趣的是,libc++的实现中的 std::any 在这里有效,而libstdc++的则无效。这似乎完全取决于相关类型特征何时被实例化,以及实现如何处理它们的缓存--我不确定。也请参见 gcc bug 90415 其中跟踪这。

以上是关于复制构造函数与使用std::any的构造函数之间的冲突。的主要内容,如果未能解决你的问题,请参考以下文章

=default 和没有参数的空构造函数之间的区别? [复制]

关于复制构造函数的几个问题

复制构造函数与赋值运算符(=)有何不同

如何在 c# 中调用与构造函数不同的构造函数? [复制]

C++——构造函数析构函数以及复制构造函数

函数重载与复制构造函数