根据类型比较分配值

时间:2017-04-20 10:47:10

标签: c++

我正在尝试制作一个模板类,根据需要,可以接受doublempfr::mpreal类型。这就是我想要做的事情:

x = ( typeid(T)==typeid(double) ? value : value.toDouble() );

但它在编译时抱怨无法在赋值中将'const mpfr :: mpreal'转换为'double'。我也试过std::is_same,但错误相同。我试图做的是禁止,或者只是错误(或两者兼而有之)?有什么方法可以做到这一点吗?每个文件中对类的调用是不同的,但是已修复,例如在一个.cpp中调用Class<double>,在另一个Class<mpfr::mpreal>中等。这是一个快速测试程序:

#include <iostream>
#include <typeinfo>
#include "mpreal.h"

template<class T>
class Bla
{
private:
    double a;
public:
    Bla(const T &x) { a = (std::is_same<T, double>::value ? x : x.toDouble()); }
    void f() { std::cout << "a = " << a << '\n'; }
};

int main()
{
    mpfr::mpreal x {1.0};
    double y {2.0};
    {
        Bla<mpfr::mpreal> a {Bla<mpfr::mpreal>(x)};
        a.f();
    }
    {
        Bla<double> a {Bla<double>(y)};
        a.f();
    }

    return 0;
}

4 个答案:

答案 0 :(得分:4)

无论实例化哪种类型T,该函数都必须是正确的。

即两者

Bla(const double &x) { a = (std::is_same<double, double>::value ? x : x.toDouble()); }

Bla(const mpfr::mpreal &x) { a = (std::is_same<mpfr::mpreal, double>::value ? x : x.toDouble()); }

必须是正确的,而且很明显,两者都没有 - doublempfr::mpreal之间没有隐式转换,double没有toDouble()成员函数

一个简单的解决方案是将转换委托给重载函数:

double to_double(double x) { return x; }
double to_double(mpfr::mpreal x) { return x.toDouble(); }

Bla(const T &x) 
    : a(to_double(x)) 
{
}

答案 1 :(得分:3)

这就是强制转换操作符的用途。在mpfr::mpreal类以及要在double上下文中使用的其他类中实现此目的:

operator double() const;

你的任务变成:

Bla(const T &x) { a = x; }

或者,更好的是,初始化列表:

Bla(const T &x) : a(x) {}

作为旁注,您试图实现的内容看起来更像是条件编译,通常使用#ifdef等来实现。除非它在您的特定情况下无法工作,因为没有预处理器构造(至少我知道),这将允许您比较类型。

如果您无法修改该外部课程,则有两种选择:

  1. 从中获取。拥有自己的类,从基地进行转换。
  2. 类似的东西:

    class myDouble : public mpfr::mpreal{
        public:
            myDouble() : mpfr::mpreal() {}
            operator double() const {return this->toDouble();}
    };
    
    1. 另一种选择是使用模板化功能并对其进行专门化。
    2. 这些方面的东西:

      template<typename T> myToDouble(const & T);
      template<> double myToDouble(const double & _d) {return _d;}
      template<> double myToDouble(const mpfr::mpreal & _d) {return _d.toDouble();}
      

      然后你的作业看起来像那样:

      Bla(const T &x) : a(myToDouble(x)) {}
      

答案 2 :(得分:2)

条件表达式必须具有单一类型,如果“true”和“false”表达式的类型不同,则必须转换它们。即使条件在编译时已知,也适用。

您可以做的是例如定义具有toDouble专业化的double模板函数:

template <typename T>
double toDouble(T const& x) {
    return x.toDouble();
}

double toDouble(double const& x) {
    return x;
} 

答案 3 :(得分:1)

我只想在类中定义两个静态辅助函数:

  • double as parameter
  • 捕获所有模板版本,该版本调用x成员

如果#include <iostream> namespace mpfr { struct mpreal { double const& toDouble()const { return d; } double d; }; } template<class T> class Bla { double a; template<class U> auto to_double(U const& u) -> decltype(u.toDouble()) { return u.toDouble(); } static double const& to_double(double const& d) { return d; } public: Bla(T const& x) : a{ to_double(x) } {} void f() { std::cout << "a = " << a << '\n'; } }; 不是双倍,则会转到模板版本。

这是一个工作示例:

main()

使用与以前相同的int main() { mpfr::mpreal x {1.1}; double y {2.2}; { Bla<mpfr::mpreal> a {Bla<mpfr::mpreal>(x)}; a.f(); } { Bla<double> a {Bla<double>(y)}; a.f(); } return 0; } 实现。

float

注意:如果您通过intis_same,使用sqoop codegen --connect jdbc:mysql://127.0.0.1/mydb --table mergetab --username root --password cloudera --outdir /user/cloudera/codegenclasses --fields-terminated-by '\t' 机制,此方法也会有效,它会失败,您必须明确赶上所有可以隐式转换为double的类型。