2016-06-07 6 views
0

Когда я пытаюсь скомпилировать этот код, он терпит неудачу: «Ошибка: статическое утверждение не выполнено: построено с ошибкой указателя нулевой функции». Линия, на которую он жалуется, - это «return nullptr». Возвращение nullptr работает с другими написанными мной функциями, которые возвращают unique_ptr. Почему это так отличается и не удается скомпилировать?Возврат 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; 
} 
+0

Если вы хотите увидеть его запустить: http://ideone.com/r0beTy – JadziaMD

ответ

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& operator=(nullptr_t) noexcept;, который вызывает constexpr unique_ptr() noexcept;, что, в свою очередь, имеет в своем выступлении:

Remarks: If this constructor is instantiated with a pointer type or reference type for the template argument D, the program is ill-formed.

+0

The 'если (массив)' 'проверить и массив = nullptr ; 'здесь бесполезны. – eepp