【问题标题】:Is it valid to have two implicit casts in constructing an object in C++?在 C++ 中构造对象时有两个隐式强制转换是否有效?
【发布时间】:2012-06-25 11:50:33
【问题描述】:

给定以下两个构造函数签名,是否可以用Couple("George", "Nora") 构造Couple?我的编译器抱怨如下所示的错误。如果我用Couple(std::string("George"), std::string("Nora")) 调用它,它可以编译。我猜隐式转换存在问题,这让我感到惊讶,因为我认为 char* 到字符串会很好。

class Person
{
    public:
        Person(const std::string& name);
};

class Couple
{
    public:
        Coordinate(const Person& p1, const Person& p2, const Optional<Person>& = Optional<Person>());
};

TestCouple.cpp:69: error: no matching function for call to `Couple::Couple(const char[7], const char[5])'
TestCouple.h:24: note: candidates are: Couple::Couple(const Person&, const Person&, const Optional<fox::Person>&)

【问题讨论】:

  • 我没有看到问题,它应该可以工作。您应该发布完整的最小测试。
  • Coordinate 是错字吗?不应该是Couple吗?
  • C++ 中没有“隐式强制转换”之类的东西。强制转换是使用特殊强制转换语法的显式转换请求。你所追求的是隐式转换。

标签: c++ constructor implicit-conversion


【解决方案1】:

确实,一个转换序列不能包含多个隐式用户定义转换;标准在 C++11 12.3/4 中指定了这一点:

最多一个用户定义的转换(构造函数或转换函数)被隐式应用于单个值。

在您的情况下,需要两个(char const[]std::stringPerson),因此无法进行隐式转换。

【讨论】:

    【解决方案2】:

    您是正确的,隐式转换存在问题。它只会对一个值进行一次隐式转换,因此您可以进行Couple(std::string("a"), std::string("b"))Couple(Person("a"), Person("b")) 之类的操作,但Couple("a", "b") 将要求编译器对每个值进行两次隐式转换。标准不允许这样做,因为这会导致代码可能难以正确理解并且编译起来计算量很大。

    【讨论】:

      【解决方案3】:

      不允许链式隐式转换。如果A可以隐式转换为BB可以隐式转换为C,那么并不意味着A可以隐式转换为C.

      //given three objects as
      A a;
      B b'
      C c;
      
      //premises 
      b = a; //a can convert into b (implicitly)
      c = b; //b can convert into c (implicitly)
      
      //then it does not follow this
      c = a; //a CANNOT convert into c (implicitly)
      
      //you need to write this at least
      c = static_cast<B>(a); //ok
      

      【讨论】:

      • 那么这并不意味着A可以隐式转换为C。”是正确的。 Nitpick:声明“b = a 有效”不等于声明“A 可以转换为 B”。
      • @curiousguy:解释一下你在说什么。为什么b=a首先在这里有效?
      • 假设 B 是一个类类型,b=a 是有效的iff 重载决议可以为b.operator=(a) 找到一个最佳匹配。您也可以写foo(a,b),以获取foo 的合适重载。
      • @curiousguy:您应该正确阅读我的回答。我说:如果A可以隐式转换成B...
      • "您应该正确阅读我的回答。" 我做到了。 "如果 A 可以隐式转换为 B ..." 那么呢?
      猜你喜欢
      • 2015-11-08
      • 1970-01-01
      • 2015-07-16
      • 1970-01-01
      • 2014-08-05
      • 2012-09-08
      • 1970-01-01
      • 2012-02-18
      • 1970-01-01
      相关资源
      最近更新 更多