解决无符号长/指针歧义
Resolve unsigned long / pointer ambiguity
我们的旧代码正在使用 RogueWave 库。我正在尝试从 0 文字构造一个 RWTime 对象。但是,我所做的任何事情似乎都没有效果,编译器仍然有两个构造函数 select from:
error: call of overloaded 'RWTime(int)' is ambiguous
_time(static_cast<unsigned long>(0))
^
note: candidates are:
RWTime::RWTime(const tm*, const RWZone&)
RWTime(const struct tm* ptm, const RWZone& zone = RWZone::local());
^
RWTime::RWTime(long unsigned int)
RWTime(unsigned long s)
^
constexpr RWTime::RWTime(const RWTime&)
class RW_DEPRECATE_TYPE("Use RWDateTime instead") RW_TOOLS_SYMBOLIC RWTime
^
constexpr RWTime::RWTime(RWTime&&)
我想使用 unsigned long
构造函数,但我似乎无法实际传递 unsigned long。我试过了:
_time(static_cast<unsigned long>(0))
_time((unsigned long)0)
_time(0UL)
_time(0)
但没有效果。也许问题在于指针具有 uintptr_t
类型,它与 size_t
类型同义,而 size_t
类型与 unsigned long
同义。然后实际上有两个构造函数采用 unsigned long
.
编辑:我检查了 RWTime class 文档,他们提到了这个问题:“编译器可以将 0 解析为整数或指针。因为还有一个构造函数接受一个指针(指向 struct tm
),如果要从unsigned long
值0构造时间,必须显式:
RWTime earlyTime((unsigned long)0);
但是,出于某种原因,它对我不起作用(使用 c++11)。
如果您可以使用 c11,则无法使用 nullptr 和 nullptr_t 解决您的问题:
当值为 0(或 NULL 也为 0)时,编译器可以在指针和 int 函数之间进行选择。
您必须定义一个接受 nullptr_t 的新函数以避免歧义:
RWTime::RWTime( std::nullptr_t np)
当然,对空指针使用std::nullptr
正如您指出的那样,无法更改库代码,我提出了第二种解决方案:
定义一个中间变量,为编译器提供线索,说明必须选择哪个函数
unsigned long tmp = 0;
_time(tmp);
另一种方法可以给第二个参数:
_time(0, RWZone::local());
如果你能接受,你可以在构造函数中把RWZone
的默认值去掉:
RWTime(const struct tm* ptm, const RWZone& zone = RWZone::local());
因此它显示为:
RWTime(const struct tm* ptm, const RWZone& zone);
那么不能取 0,因为 RWZone
参数会丢失。
当然你可以添加一个静态方法,允许你创建一个只需要 const struct tm*
的 RWTime
对象,如下所示:
static RWTime create(const struct tm* ptm) { return RWTime(ptr, RWZone::local()); }
原来我看错了一段代码。
_time(0UL)
很有魅力。
我们的旧代码正在使用 RogueWave 库。我正在尝试从 0 文字构造一个 RWTime 对象。但是,我所做的任何事情似乎都没有效果,编译器仍然有两个构造函数 select from:
error: call of overloaded 'RWTime(int)' is ambiguous
_time(static_cast<unsigned long>(0))
^
note: candidates are:
RWTime::RWTime(const tm*, const RWZone&)
RWTime(const struct tm* ptm, const RWZone& zone = RWZone::local());
^
RWTime::RWTime(long unsigned int)
RWTime(unsigned long s)
^
constexpr RWTime::RWTime(const RWTime&)
class RW_DEPRECATE_TYPE("Use RWDateTime instead") RW_TOOLS_SYMBOLIC RWTime
^
constexpr RWTime::RWTime(RWTime&&)
我想使用 unsigned long
构造函数,但我似乎无法实际传递 unsigned long。我试过了:
_time(static_cast<unsigned long>(0))
_time((unsigned long)0)
_time(0UL)
_time(0)
但没有效果。也许问题在于指针具有 uintptr_t
类型,它与 size_t
类型同义,而 size_t
类型与 unsigned long
同义。然后实际上有两个构造函数采用 unsigned long
.
编辑:我检查了 RWTime class 文档,他们提到了这个问题:“编译器可以将 0 解析为整数或指针。因为还有一个构造函数接受一个指针(指向 struct tm
),如果要从unsigned long
值0构造时间,必须显式:
RWTime earlyTime((unsigned long)0);
但是,出于某种原因,它对我不起作用(使用 c++11)。
如果您可以使用 c11,则无法使用 nullptr 和 nullptr_t 解决您的问题: 当值为 0(或 NULL 也为 0)时,编译器可以在指针和 int 函数之间进行选择。
您必须定义一个接受 nullptr_t 的新函数以避免歧义:
RWTime::RWTime( std::nullptr_t np)
当然,对空指针使用std::nullptr
正如您指出的那样,无法更改库代码,我提出了第二种解决方案: 定义一个中间变量,为编译器提供线索,说明必须选择哪个函数
unsigned long tmp = 0;
_time(tmp);
另一种方法可以给第二个参数:
_time(0, RWZone::local());
如果你能接受,你可以在构造函数中把RWZone
的默认值去掉:
RWTime(const struct tm* ptm, const RWZone& zone = RWZone::local());
因此它显示为:
RWTime(const struct tm* ptm, const RWZone& zone);
那么不能取 0,因为 RWZone
参数会丢失。
当然你可以添加一个静态方法,允许你创建一个只需要 const struct tm*
的 RWTime
对象,如下所示:
static RWTime create(const struct tm* ptm) { return RWTime(ptr, RWZone::local()); }
原来我看错了一段代码。
_time(0UL)
很有魅力。