gpt4 book ai didi

c++ - SFINAE 重复构造函数声明

转载 作者:行者123 更新时间:2023-11-30 03:51:38 28 4
gpt4 key购买 nike

我想以编译器在需要时简单地创建它的新实例的方式为类创建构造函数。

这是一个例子。

class C {
public:
C(int) {}; // int constructor
};

如果我然后声明一个函数:

void F(C _c) {};

我可以用一个 int 调用它,并让编译器处理 C 的构造:

F(0); // works

我想做的是实现同样的事情,但是使用 lambdas 作为参数,举几个例子:

F([]() {});                     //A
F([](int) {}); //B
F([](int)->int { return 0; }); //C

使用 SFINAE 以及我从另一个问题中学到的知识:Auto-constructor not working with <functional> objects

我设法找出一种方法来创建一个仅匹配特定 lambda 签名的构造函数,结果如下:

template<typename F, typename = decltype(function<void(void)>(declval<F&>()))> C(F&& f) {}; //For lambda's like A
template<typename F, typename = decltype(function<void(int)>(declval<F&>()))> C(F&& f) {}; //For lamdba's like B
template<typename F, typename = decltype(function<int(int)>(declval<F&>()))> C(F&& f) {}; //For lambda's like C

现在我遇到的问题是,如果我同时添加这三个定义,我会收到一条错误消息,指出我正在尝试重新定义 C 的构造函数。这是正确的,因为,是的,构造函数被定义为 C (F&& f) 但是,我应该如何让编译器知道针对每个不同的情况使用不同的签名?

另一个答案提示我查看 enable_if 和 is_convertible 但还没有设法为这个问题设置解决方法。非常感谢任何帮助。

使用:Apple LLVM 版本 6.0 (clang-600.0.57)(基于 LLVM 3.5svn)

最佳答案

你现在的问题是你定义了3次

template <typename F, typename> C(F&&);

但使用不同的默认参数(执行 SFINAE)。

您可以更改为

// Use to have different type easily
template <std::size_t> struct dummy {}

template<typename F, decltype(function<void(void)>(declval<F&>()), dummy<0>())* = nullptr> C(F&& f);
template<typename F, decltype(function<void(int)>(declval<F&>()), dummy<1>())* = nullptr> C(F&& f);
template<typename F, decltype(function<int(int)>(declval<F&>()), dummy<2>())* = nullptr> C(F&& f);

所以你有 3 个不同的签名:

template<typename F, dummy<0>*> C(F&& f);
template<typename F, dummy<1>*> C(F&& f);
template<typename F, dummy<2>*> C(F&& f);

关于c++ - SFINAE 重复构造函数声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31152476/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com