【问题标题】:Returning nullptr for unique_ptr with custom deleter fails使用自定义删除器为 unique_ptr 返回 nullptr 失败
【发布时间】:2016-06-07 12:10:16
【问题描述】:

当我尝试编译这段代码时,它失败了: “错误:静态断言失败:用空函数指针删除器构造”。它抱怨的那一行是“return nullptr”。返回 nullptr 可与我编写的返回 unique_ptr 的其他函数一起使用。为什么会如此不同,甚至无法编译?

#include <iostream>
#include <memory>

template<typename ArrayType>
void deleter(ArrayType* array) noexcept
{
    if (array)
    {
        delete[] array;
        array = nullptr;
        std::cout << "Freed array." << std::endl;
    }
}
template<typename ArrayType>
std::unique_ptr<ArrayType[], decltype(&deleter<ArrayType>)> makeArray(const std::size_t size)
{
    return std::unique_ptr<ArrayType[], decltype(&deleter<ArrayType>)>{
        new ArrayType[size],
        deleter<ArrayType>
    };
}

std::unique_ptr<int[], decltype(&deleter<int>)> createInt(int s)
{
    if (s == 3)
        return makeArray<int>(3);
    else
        return nullptr;
}

void testArr(int arr[])
{
    if (arr != nullptr)
    {
        arr[0] = 1;
        arr[1] = 2;
        arr[2] = 3;
        std::cout << "Value 2 is " << arr[1] << std::endl;
    }
    else
        std::cout << "Array is empty." << std::endl;
}

int main() {
    auto arr0{createInt(4)}, arr1{createInt(3)};
    std::cout << "\tTesting arr0:\n";
    testArr(arr0.get());
    std::cout << "\tTesting arr1:\n";
    testArr(arr1.get());
    std::cout << "\tFinished testing\n";
    return 0;
}

【问题讨论】:

标签: c++ templates compiler-errors c++14


【解决方案1】:

看来您需要使用函数对象,例如:

template<typename ArrayType>
struct deleter {
    void operator()(ArrayType* array) {
    if (array)
    {
        delete[] array;
        array = nullptr;
        std::cout << "Freed array." << std::endl;
    }
    }
};

看这里的例子:

http://coliru.stacked-crooked.com/a/172693cdc5704531

我认为标准的相关部分在 20.8.1.2.1 [unique.ptr.single.ctor]

返回你调用的nullptr:unique_ptr&amp; operator=(nullptr_t) noexcept;,它调用constexpr unique_ptr() noexcept;,它又在备注中:

备注:如果这个构造函数是用指针类型实例化的,或者 模板参数 D 的引用类型,程序格式错误。

【讨论】:

  • if (array) check 和 array = nullptr; 语句在这里没用。
猜你喜欢
  • 1970-01-01
  • 2013-03-30
  • 2018-10-16
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-13
相关资源
最近更新 更多