自定义类没有可行的int转换

时间:2014-07-16 15:31:02

标签: c++

我编写了一个UTF8字符类,使用以下方法:

typedef uint32_t CodePoint; // This is meant to represent any unicode character

explicit Char(const char c);
explicit Char(const CodePoint cp);

Char& operator=(const char c);
Char& operator=(const CodePoint cp);

但是当我尝试通过传递一个数字来构造我的一个新类时,我得到一个错误:

utf8::Char c = 0x20AC; // No viable conversion from int to utf8::Char
utf8::Char c(0x20AC);  // Call to constructor of 'utf8::Char' is ambiguous

为什么我会看到这些错误?

2 个答案:

答案 0 :(得分:1)

  

typedef uint32_t CodePoint; // This is meant to represent any unicode character

您是否意识到C ++ 11为此目的定义了一个独特的char32_t类型?

  

utf8::Char c = 0x20AC; // No viable conversion from int to utf8::Char

这不是作业,而是一种结构。此语法称为复制初始化,等同于:

utf8::Char c = utf8::Char(0x20AC);

除了从intutf8::Char的转换是隐式的,因此无法使用explicit构造函数。

  

utf8::Char c(0x20AC); // Call to constructor of 'utf8::Char' is ambiguous

intchar的转换并不比从int转换为uint32_t更好或更差。

  

有没有办法说“除CodePoint之外的所有内容都使用char构造函数”。

是的,在C ++类型系统中说“所有”的常用方法是模板:

explicit Char(char c);
template<typename T>
  explicit Char(T cp);

当参数为Char(char)时,char构造函数将是首选(因为重载决策更喜欢非模板,如果它们不是模糊的,则优先于模板),对于其他所有构造函数模板,使用。

因为您不希望模板构造函数接受每个类型,所以如果使用非整数类型调用它,则可能需要使其成为错误。在C ++ 11中,您可以这样做:

template<typename T>
  explicit Char(T cp)
  {
    static_assert(std::is_integral<T>::value, "utf8::Char should only be constructed from integral types");
  }

答案 1 :(得分:-3)

0x20AC是数字,因此您必须提供另一个重载构造函数。