Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从int到shared_ptr的隐式转换_C++_C++11_Type Conversion_Shared Ptr_Implicit Conversion - Fatal编程技术网

C++ 从int到shared_ptr的隐式转换

C++ 从int到shared_ptr的隐式转换,c++,c++11,type-conversion,shared-ptr,implicit-conversion,C++,C++11,Type Conversion,Shared Ptr,Implicit Conversion,考虑以下代码: #include <iostream> #include <memory> void f(std::shared_ptr<int> sp) {} template <typename FuncType, typename PtrType> auto call_f(FuncType f, PtrType p) -> decltype(f(p)) { return f(p); } int main() { f

考虑以下代码:

#include <iostream>
#include <memory>

void f(std::shared_ptr<int> sp) {}

template <typename FuncType, typename PtrType>
auto call_f(FuncType f, PtrType p) -> decltype(f(p))
{
    return f(p);
}

int main()
{
    f(0); // doesn't work for any other int != 0, thanks @Rupesh
    // call_f(f, 0); // error, cannot convert int to shared_ptr
}
我的问题是:

  • 为什么第一个呼叫成功,第二个呼叫没有成功?这里有我遗漏的东西吗
  • 我也不明白在调用
    f(0)
    中如何执行从
    int
    std::shared\u ptr
    的转换,因为看起来
    std::shared\u ptr
    只有显式构造函数

    PS:这个例子的变体出现在Scott Meyers的“有效的现代C++项目8”中,作为一种保护方法,用“代码> NulLPTR < /C> > < /P> < P>每[UNI.PTR] / 1(引用N429 6)(<4/6): 空指针常量是值为零的整数文本(2.13.2)或类型为

    std::nullptr\t
    的prvalue。。。整数类型的空指针常量可以转换为
    std::nullptr\u t
    类型的prvalue

    shared\u ptr
    有一个非显式构造函数,它根据[util.smartptr.shared.const]/1接受
    std::nullptr\u t

    constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { }
    
    它构造了一个空的、非所有的
    共享\u ptr

    直接调用
    f(0)
    时,
    0
    是一个空指针常量,由上述构造函数隐式转换为
    shared_ptr
    。当您改为调用
    call_f(f,0)
    时,文本0的类型被推断为
    int
    ,当然
    int
    不能转换为
    共享的\u ptr

    具有采用std::nullptr\t的构造函数,文字>代码> 0代码>代码是一个空指针常数,它可从C++标准部分草案<代码> 4.10代码> [CON.PTR](强调前进的)转换到: 空指针常量是整数类型的整型常量表达式(5.19)prvalue,其计算结果为零或类型为prvalue std::nullptr\u t。空指针常量可以转换为 指针类型;结果是该类型的空指针值,为 与对象指针或函数的其他值不同 指针类型。这种转换称为空指针转换。 相同类型的两个空指针值应相等。这个 将空指针常量转换为cv限定的指针 类型是单个转换,而不是指针序列 转换之后是资格转换(4.4)空值 整数类型的指针常量可以转换为PRV值 类型std::nullptr\u t。[注意:结果prvalue不是空值 指针值。-结束注释]

    在第二种情况下,
    p
    被推断为int类型,尽管其值为零,但它不再是空指针常量,因此不适合相同的情况

    正如T.C.所指出的,措辞发生了变化,需要一个值为零的整型文字,而不是一个计算结果为零的整型常量表达式:

    空指针常量是带值的整数文本(2.14.2) 零或std::nullptr\t类型的PR值。空指针常量 可以转换为指针类型;结果是空指针 该类型的值,并可与 对象指针或函数指针类型

    第一个调用f(0)被编译为f(nullptr),这对编译器来说很好(但我认为不应该是这样)。第二个调用将为一个函数创建一个声明来处理任何int,这是非法的

    有趣的是,即使是这样的代码也能工作:

    f(3-3);
    f(3*0); 
    

    @@vsoftco您应该提到,它仅适用于
    f(0)
    ,除了零之外,没有任何内容正在编译,即使在第一次调用中,其他值也会出现相同的错误。提示说明-“存在从nullptr到任何指针类型的null指针值和任何指向成员类型的指针的隐式转换。std::nullptr__t类型的任何值以及null指针常量宏null都存在类似的转换。”但如果能用标准的参考资料和更清晰的解释,那将是一件有趣的事情。@RupeshYadav。完成。确实,这很奇怪,看起来某种隐式指针转换是有穿透力的。当然,答案是有趣的。在C++中,零是非常可转换的,F(false)和F(′0)之类的东西应该也能正常工作。是的,读完上面的答案是有意义的。代码
    f(3-3)
    正常,因为
    3-3
    3*0
    是一个评估为0的PR值。“空指针常量是一个整数类型的积分常量表达式(5.19)prvalue,其计算结果为零或类型为std::nullptr_t。”另一方面,
    int x=0;f(x)
    不再有效,因为
    x
    不再是PR0值,而是左值,因此不再是空指针常量。可能需要使用更更新的草稿(请参见下面的@Casey答案)。IIRC“计算结果为零的整数类型的整数常量表达式(5.19)prvalue”包括
    (3*5+8-7)/4-4
    ,对于涉及非类型模板参数的非依赖调用,它与重载解析进行了奇怪的交互,因此他们仅在DR中将其更改为文字零。@BenVoigt似乎是这样,虽然我同意,但我更喜欢文字上的零。也许暂时支持积分常量表达式作为扩展会有所帮助。
    f(3-3);
    f(3*0);