繁体   English   中英

在构造函数中增强enable_if

[英]Boost enable_if in constructor

我有一个模板化的类,并且我只想在类型为double时启用某个构造函数。 此代码有什么问题?

template<typename T>
class B: public A<T>
{
public:
    B(int arg1=0, typename boost::enable_if_c<boost::is_same<T, double>::value>=0);
}

int main(int argc,char *argv[])
{
B<double> B( 6, 6 );
}

我收到错误消息:“类型为'boost :: enable_if_c'的参数的默认参数的类型为'int'””但是我不确定这是什么意思。

提前非常感谢您。

好吧,你不能真正做到这一点。 如果提供的T不是double ,那么编译器将尝试解析enable_if_c<false>::type ,这将失败,从而使整个类实例化失败,而不仅仅是构造函数。

您可以使用C ++ 11的默认函数模板参数来实现相同目的。

下面的代码使用您在代码中使用的boost功能的C ++ 11版本来实现:

#include <type_traits>

template<typename T>
class B {
public:
    // T == double -> this ctor can be used
    template<typename U = T, class = typename std::enable_if<std::is_same<U, double>::value>::type>
    B(int arg1, double arg2) {}

    // Default ctor, available to every class.
    B() {}
};

int main(int argc,char *argv[])
{
    B<double> b_double( 6, 6 );
    B<int> b_int;

    // This line fails
    //B<int> b_fails(6, 6);
}

在这种情况下,您不能使用SFIANE,因为它仅在函数模板参数的替换失败时起作用 ,而在模板参数的替换失败时不起作用。

您需要的是专业化

但是据我了解,您应该在double情况下复制普通情况的实现,而只能添加新的构造函数。

在这种情况下,我建议我使用一些有线技术:您可以从专业中的常见情况中得出。

然后您会遇到2个问题:

  1. 您仍应具有double专业化常见案例
  2. 您不应调用普通情况下的默认构造函数,而应调用一些专门的构造函数。

我们去了:

template<typename T, bool = false>
class B
{
public:
    B() { std::cout << "B common\n"; }
    void yahoo() { std::cout << "yahoo!\n"; }

protected:
    struct internal_t;
    B(internal_t*){}

};

template <>
struct B<double, false>: public B<double, true>
{
    B(int, int):B<double, true>(0) { std::cout << "B double\n"; }
};

int main(int argc,char *argv[])
{
    B<int> ib;
    B<double> b(2,5);

    ib.yahoo();
    b.yahoo();
}
B(int arg1=0, typename boost::enable_if_c<boost::is_same<T, double>::value>=0);

您忘记了boost::enable_if_c的第二个参数,该参数指定了类型,忘记了::type ,并且忘记了参数名称。

如果您想要沿着B(int arg1=0, int arg2=0) ,请使用

B(int arg1=0,
  typename boost::enable_if_c<boost::is_same<T, double>::value, int>::type arg2=0);

更好的是,请勿使用下划线c版本的enable if。 仅在以下情况下使用启用:

B(int arg1=0,
  typename boost::enable_if<boost::is_same<T, double>, int>::type arg2=0);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM