类型转换,显式构造函数等

时间:2015-11-19 23:06:21

标签: c++ oop c++11 constructor type-conversion

我有BigNum课程。 我需要实现什么样的方法,构造函数等才能产生预期效果(如评论中)?

class BigNum {
    //...?
};

BigNum a = 1; // compiles
a = 42; // compiles
BigNum b = 1L; // compiles
BigNum c = 1U; // compiles
BigNum d = 1UL; // compiles
BigNum e = true; // doesn't compile
BigNum f = '1'; // doesn't compile

4 个答案:

答案 0 :(得分:3)

BigNum a = 1; //compiles
BigNum b = 1L; //compiles
BigNum c = 1U; //compiles
BigNum d = 1UL; //compiles
BigNum e = true; //doesn't compile
BigNum f = '1'; //doesn't compile

对于这些,您需要非显式构造函数,它们将接受除boolchar之外的整数类型。您可以编写一整套完整的重载,如std::to_string的重载。请注意,对于小于int的类型,您不需要重载,因为它们可以毫无歧义地提升为intunsigned int。您可以将所有这些调用委托给long longunsigned long long版本,并且只实现这两个版本。

// remember to define these
BigNum(unsigned long long x);
BigNum(long long x);
BigNum(unsigned long x);
BigNum(long x);
BigNum(unsigned int x);
BigNum(int x);

要禁用boolchar,您可以删除这些构造函数。那么你想要错误的那些行会出错。如果你不这样做,他们只会升级到int,所以不会有错误。

BigNum(bool x) = delete;
BigNum(char x) = delete;
// you might also want to delete these:
// BigNum(char16_t x) = delete;
// BigNum(char32_t x) = delete;

另一种方法是定义一个接受任何整数类型的构造函数模板,然后像以前一样为boolchar定义其他已删除的重载。这避免了必须编写多个实现。

template <typename Integral, typename = std::enable_if_t<std::is_integral<Integral>::value>>
BigNum(Integral i);
BigNum(bool b) = delete;
BigNum(char c) = delete;
a = 42; //compiles

为此你需要赋值运算符。你可能只想在这里玩同样的游戏。

// remember to define these
BigNum& operator=(unsigned long long x);
BigNum& operator=(long long x);
// you can delegate these to the above
BigNum& operator=(unsigned long x);
BigNum& operator=(long x);
BigNum& operator=(unsigned int x);
BigNum& operator=(int x);
BigNum& operator=(bool x) = delete;
BigNum& operator=(char x) = delete;
// BigNum& operator=(char16_t x) = delete;
// BigNum& operator=(char32_t x) = delete;

答案 1 :(得分:2)

实际上并非如此简单,因为boolchar将隐式转换为其他整数类型。但我已经做到了:

class BigNum {
public:
    template <
        typename T,
        typename = typename std::enable_if<std::is_integral<T>::value &&
            !std::is_same<T, bool>::value && !std::is_same<T, char>::value>::type>
    BigNum(T) {}
};

答案 2 :(得分:0)

我建议使用模板和 std :: static_assert

struct BigNum {

    template <typename Int> BigNum(Int val)
    {
        std::static_assert(std::is_integral<Int>::value,"must be integral");
        std::static_assert(!std::is_same<Int,bool>::value,"can not be bool");
        std::static_assert(!std::is_same<Int,char>::value,"can not be char");

        // ...
    }
};

您可以类似地为operator=

执行此操作

答案 3 :(得分:-1)

鉴于此

a = 42; //compiles

您还需要一个赋值运算符。 简单的例子:

BigNum& operator=(const int n)
{
    // relevant stuff here...
    return *this;
}