SFINAE复制构造函数声明 [英] SFINAE Duplicate constructor declaration

查看:72
本文介绍了SFINAE复制构造函数声明的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为类创建构造函数,以便编译器在需要时轻松创建类的新实例。

I want to create constructors for a class in a way that the compiler trivially create new instances of it when needed.

这里是一个示例。

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

然后我声明一个函数:

void F(C _c) {};

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

I can call this one with an int and have the construction of C handled by the compiler:

F(0); // works

我想做的是实现相同的事情,但是使用lambda作为参数,一些例子:

What I want to do is to achieve the same thing, but with lambdas as parameters, a few examples:

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

有了SFINAE,从另一个问题中我学到了以下内容:自动构造函数无法与< functional>对象

With SFINAE and from what I've learned from another question: Auto-constructor not working with <functional> objects

我设法找到一种创建仅匹配特定lambda签名的构造函数的方法,它的工作方式如下:

I managed to sort out a way to create a constructor that matches only a specific lambda signature, it would work out like this:

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)三次,但是,我应该如何知道

Now the problem that I have is that if I add these three definitions at once, I get an error stating that I'm trying to redefine the constructor of C. This is correct because, yeah, the constructor's being defined as C(F&& f) three times, however, how should I let know the compiler to use a different signature for each different case?

另一个答案提示我看一下enable_if和is_convertible,但没有设法解决此问题。

The other answer hinted me to look at enable_if and is_convertible but haven't managed to set up a workaround for this issue. Any help is greatly appreciated.

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

Using: Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn)

推荐答案

您当前的问题是您定义了3次

Your current problem is that you define 3 times

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

但具有不同的默认参数(做SFINAE)。

but with different default argument (to do 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种不同的签名:

So you have 3 different signatures:

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

这篇关于SFINAE复制构造函数声明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆