From 0f2a7d19a333fa8807b9d0386d551940104a6db0 Mon Sep 17 00:00:00 2001 From: racaljk <1948638989@qq.com> Date: Fri, 8 Jun 2018 16:38:13 +0800 Subject: [PATCH] Iterm11 : accomplish --- 3.MovingToModernCpp/item11.md | 45 +++++++++++++++++++++++++++-------- README.md | 1 - 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/3.MovingToModernCpp/item11.md b/3.MovingToModernCpp/item11.md index 8d086af..e5480a4 100644 --- a/3.MovingToModernCpp/item11.md +++ b/3.MovingToModernCpp/item11.md @@ -88,15 +88,40 @@ void processPointer(const void*) = delete; template<> void processPointer(const char*) = delete; ``` -And if you really want to be thorough, you’ll also delete the const volatile void* -and const volatile char* overloads, and then you’ll get to work on the overloads -for pointers to the other standard character types: std::wchar_t, std::char16_t, -and std::char32_t. +如果你想做得更彻底一些,你还要删除`const volatile void*`和`const volatile char*`重载版本,另外还需要一并删除其他标准字符类型的重载版本:`std::wchar_t`,`std::char16_t`和`std::char32_t`。 -Interestingly, if you have a function template inside a class, and you’d like to disable -some instantiations by declaring them private (à la classic C++98 convention), you -can’t, because it’s not possible to give a member function template specialization a -different access level from that of the main template. If processPointer were a -member function template inside Widget, for example, and you wanted to disable -calls for void* pointers, this would be the C++98 approach, though it would not +有趣的是,如果的类里面有一个函数模板,你可能想用`private`(经典的C++98惯例)来禁止这些函数模板实例化,但是不能这样做,因为不能给特化的模板函数指定一个不同的访问级别。如果`processPointer`是类`Widget`里面的模板函数, 你想禁止它接受`void*`参数,那么通过下面这样C++98的方法就不能通过编译: compile: +```cpp +class Widget { +public: + … + template + void processPointer(T* ptr) + { … } +private: + template<> // 错误! + void processPointer(void*); +}; +``` +问题是模板特例化必须位于一个命名空间作用域,而不是类作用域。`delete`不会出现这个问题,因为它不需要一个不同的访问级别,且他们可以在类外被删除(因此位于命名空间作用域): +```cpp +class Widget { +public: + … + template + void processPointer(T* ptr) + { … } + … +}; +template<> +void Widget::processPointer(void*) = delete; // 还是public,但是已经被删除了 +``` +事实上C++98的最佳实践即声明函数为*private*但不定义是在做C++11 delete函数要做的事情。作为模仿者,C++98的方法不是十全十美。它不能在类外正常工作,不能总是在类中正常工作,它的罢工可能直到链接时才会表现出来。所以请坚定不移的使用`delete`函数。 + + +记住: ++ 比起声明函数为private但不定义,使用delete函数更好 ++ 任何函数都能`delete`,包括非成员函数和模板实例 + +_译注:本条款`delete`,`deleted`,`删除`视情况使用,都表示一个意思.`删除函数`和`delete函数`也是如此_ diff --git a/README.md b/README.md index 52f2a7f..194b9a3 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,6 @@ 3. [Item 9:优先考虑别名声明而非typedefs](https://github.com/racaljk/EffectiveModernCppChinese/blob/master/3.MovingToModernCpp/item9.md) 4. [Item 10:优先考虑限域枚举而非未限域枚举](https://github.com/racaljk/EffectiveModernCppChinese/blob/master/3.MovingToModernCpp/item10.md) _revised_ 5. [Item 11:优先考虑使用deleted函数而非使用未定义的私有声明](https://github.com/racaljk/EffectiveModernCppChinese/blob/master/3.MovingToModernCpp/item11.md) - _updating_ 6. Item 12:使用override声明重载函数 7. Item 13:优先考虑const_iterator而非iterator 8. Item 14:如果函数不抛出异常请使用noexcept