SFINAE复制构造函数声明 [英] SFINAE Duplicate constructor declaration
问题描述
我想为类创建构造函数,以便编译器在需要时轻松创建类的新实例。
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屋!