零比率与char *模糊不清

时间:2015-06-22 14:07:34

标签: c++

我在C ++中有一个方便的类,可以使用doublechar*进行初始化。一切都按预期工作,除了参数为零的一种情况。

struct Var {
    Var (double src) {}
    Var (char *src) {}
};

int main(int argc, char* argv[]) {
    Var A = 123;
    Var B = "abc";
    Var C = 0; <- Error: conversion from 'int' to 'Var' is ambiguous
}

之前我使用的是int而不是double,并且由于某种原因它没有问题。

如何解决这个问题?

PS:我知道我可以使用(double)0或仅0.0,但有没有办法让0被接受为?< / p>

2 个答案:

答案 0 :(得分:11)

您可以通过添加第三个构造函数来消除歧义,该构造函数需要int并委托给double版本(需要C ++ 11):

struct Var {
    Var (double src) {}
    Var (const char *src) {}
    //   ^^^^^ should be const
    Var (int src) : Var {static_cast<double>(src)} {}
};

但是,通过更改char*构造函数以取代std::string并使用直接初始化,可以更轻松地解决此问题。

答案 1 :(得分:7)

在C ++中,文字0的类型为int。你不能改变它是一个整数的任何东西,不添加至少一个小数点。 (虽然没有实际需要在点之后写数字)

回答关于为什么电话与123明确无误但与0含糊不清的隐含问题:

  • 初始化A时,它很好,因为没有从int到指针的隐式转换(在这种情况下为char*)。

  • 当您第二次使用int初始化C时,您使用了0,文字0可以隐式转换为指针(某些遗留行为,在C之前) ++ 11提供了nullptr字面值。

所以,简而言之:

int * a = 0; // legal;
int * b = 2; // ILLEGAL;

初始化C时需要进行一次转换以将参数提供给两个可用构造函数中的任何一个(并且两个转换具有相同的排名),调用是不明确的。

为了使其明确无误,您应该将int文字转换为double((double)0),使用双重文字(0.),或者添加一个带int的构造函数。 使用最后一个解决方案,构造函数采用int是完全匹配,因此它是另一个需要转换的重载(这就是为什么会被选中)的更好匹配。

编辑。请注意,这里应该接受 TartanLlama 答案,因为它是最好的C ++实践:采用C风格字符串的构造函数应该采用std::string。由于存在从C样式字符串到std::string的隐式转换,因此调用几乎没有变化:

Var B("abc");

但是你会将你的类接口与指针细节隔离开来。