C++ 在C+中有条件地启用构造函数+;班
我正在学习如何使用C++ 在C+中有条件地启用构造函数+;班,c++,constructor,enable-if,C++,Constructor,Enable If,我正在学习如何使用std::enable_if,到目前为止,我在有条件地启用和禁用类中的方法方面取得了一定程度的成功。我根据一个布尔值对方法进行模板化,这种方法的返回类型是这种布尔值的std::enable_。这里的最小工作示例: #include <array> #include <iostream> #include <type_traits> struct input {}; struct output {}; template <class
std::enable_if
,到目前为止,我在有条件地启用和禁用类中的方法方面取得了一定程度的成功。我根据一个布尔值对方法进行模板化,这种方法的返回类型是这种布尔值的std::enable_。这里的最小工作示例:
#include <array>
#include <iostream>
#include <type_traits>
struct input {};
struct output {};
template <class io> struct is_input { static constexpr bool value = false; };
template <> struct is_input<input> { static constexpr bool value = true; };
template <class float_t, class io, size_t n> class Base {
private:
std::array<float_t, n> x_{};
public:
Base() = default;
Base(std::array<float_t, n> x) : x_(std::move(x)) {}
template <class... T> Base(T... list) : x_{static_cast<float_t>(list)...} {}
// Disable the getter if it is an input class
template <bool b = !is_input<io>::value>
typename std::enable_if<b>::type get(std::array<float_t, n> &x) {
x = x_;
}
// Disable the setter if it is an output class
template <bool b = is_input<io>::value>
typename std::enable_if<b>::type set(const std::array<float_t, n> &x) {
x_ = x;
}
};
int main() {
Base<double, input, 5> A{1, 2, 3, 4, 5};
Base<double, output, 3> B{3, 9, 27};
std::array<double, 5> a{5, 6, 7, 8, 9};
std::array<double, 3> b{1, 1, 1};
// A.get(a); Getter disabled for input class
A.set(a);
B.get(b);
// B.set(b); Setter disabled for input class
return 0;
}
编译器错误如下所示:
In instantiation of ‘struct Base<output>’ -- no type named ‘type’ in ‘struct std::enable_if<false, void>’
在“struct Base”的实例化中--“struct std::enable_if”中没有名为“type”的类型
如前所述,当类temnplate被实例化时,它会实例化它的所有成员声明(尽管不一定是它们的定义)。该构造函数的声明格式错误,因此无法实例化该类
你将如何回避这个问题?我感谢任何帮助:)
编辑:
我想要以下的东西:
struct positive{};
struct negative{};
template <class float_t, class io> class Base{
private:
float_t x_;
public:
template <class T = io, typename = typename std::enable_if<
std::is_same<T, positive>::value>::type>
Base(x) : x_(x) {}
template <class T = io, typename = typename std::enable_if<
std::is_same<T, negative>::value>::type>
Base(x) : x_(-x) {}
struct-positive{};
结构负{};
模板类基{
私人:
浮动x;
公众:
模板::类型>
碱基(x):x_ux{}
模板::类型>
碱基(x):x_ux{}
如果可能的话。构造函数有两种方法,因为您不能在返回类型中使用它
默认模板参数:
template <class io> class Base
{
private:
float_t x_;
public:
template <class T = io,
typename std::enable_if<std::is_equal<T, input>::value, int>::type = 0>
Base() : x_{5.55} {}
};
失败的投票者能解释他失败的原因吗?可能是因为一个简单的搜索发现了一个重复的。那么为什么不以重复的形式关闭呢?我理解你指出的问题。如果构造函数不是针对类参数模板化的,而是针对它自己的参数模板化的,我们可以使用。但这里不是这样。是否有任何wa我已经对我的问题进行了编辑,以使其更加清晰。谢谢你的回答!:)编辑后,可以在编辑中指出你的另一个问题。这是一些非常有价值的见解(对我来说)关于默认参数和签名!但是对于具有int
的解决方案,该方法对于std::enable_if::type
没有被禁用。它仍然可以编译得非常好。我现在想,也许std::conditional
就是我要找的,对吧?std::enable_if::type
是一个硬错误,std::enable_if::type
和cond::value
一起生成false将不允许重载。std::conditional
似乎不是您想要的。您完全正确!我编译的文件与我发布的文件略有不同,在这里调用了不同的构造函数。是的,这正是我需要的。thank你!
template <class io> class Base
{
private:
float_t x_;
public:
template <class T = io,
typename std::enable_if<std::is_equal<T, input>::value, int>::type = 0>
Base() : x_{5.55} {}
};
template <class io> class Base{
private:
float_t x_;
public:
template <class T = io>
Base(typename std::enable_if<std::is_equal<T, input>::value, int>::type = 0) :
x_{5.55}
{}
};
template <class T = io, typename = typename std::enable_if<
std::is_same<T, positive>::value>::type>
Base(x) : x_(x) {}
template <class T = io, typename = typename std::enable_if<
std::is_same<T, negative>::value>::type>
Base(x) : x_(-x) {}
template <class, typename>
Base::Base(x);
typename std::enable_if<std::is_same<T, input>::value, int>::type = 0