我编写了一个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
为什么我会看到这些错误?
答案 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);
除了从int
到utf8::Char
的转换是隐式的,因此无法使用explicit
构造函数。
utf8::Char c(0x20AC); // Call to constructor of 'utf8::Char' is ambiguous
从int
到char
的转换并不比从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是数字,因此您必须提供另一个重载构造函数。