【问题标题】:How narrow should a using declaration be?using 声明应该有多窄?
【发布时间】:2013-02-22 22:37:25
【问题描述】:

我有一个使用std::string 的小类widget。它在许多地方使用它,通常与std::vector 结合使用。所以你可以看到,类型名变得很长而且很烦人。

我想使用using关键字,即using std::string;

问题是,放置它的最佳位置在哪里?

// widget.h file
#ifndef WIDGET
#define WIDGET

// (1)
namespace example {
    // (2)

    namespace nested {
        // (3)

        class widget {  
        public:
            // (4)
            ...
        private:
            // (5)
            std::string name_;
            ...
        };

    }
}

#endif

我的问题是:

  1. 如果我将它放在(1) 中,那么包括widget.h 的每个人的范围都会被string 污染?
  2. (2)(3) 的地方,它与1 中的情况相同。只是命名空间exampleexample::nested 将在包含widget.h 的第二个文件中被污染?
  3. (4)(5) 的地方,声明是相当孤立的,但它会在实现 (Cpp) 文件和继承类中可见吗?

提前致谢!

【问题讨论】:

  • 我认为这取决于你到底想要什么。我想最好的放置位置是您只需要使用它的地方。如果你只想在课堂上使用它,那么 4 和 5 是合理的。
  • 虽然位置 4 和 5 似乎是完美的选择,但我无法让 g++ 接受 - 我得到 using-declaration for non-member at class scope
  • 但是using base_class::shadowed_function 有效吗?

标签: c++ namespaces using


【解决方案1】:

不要在 (1) 中这样做。
每个人都会诅咒你的名字一千年。
作为您班级的用户,我不介意您污染自己的命名空间。但是如果你污染了我的任何命名空间(包括全局),我会感到不安,因为这会影响我的代码的编译方式。 Why is "using namespace std" considered bad practice?

您不能在 (4) 或 (5) 处使用它。

因为我(个人)希望将它绑定到尽可能靠近使用点(以防止污染)。
你能做的最好的是(3)。

但我什至不会那样做。我对标准中的任何事情都很明确。但我会 typedef 我的容器类型。

private: //(so at 5) Don't need to expose internal details of your class.
    typedef std::vector<std::string>   MyCont;

这是一种更好的技术,因为您只需要在一个地方进行更改,更改就会级联。

// Sub typedefs now will no longer need to change if you change
// The type of container. Just change the container typedef and
// now the iterators are automatically correct.
public: //(so at 4)  Iterators are public (and not exposing the implementation).
    typedef MyCont::iterator       iterator;
    typedef MyCont::const_iterator const_iterator;

【讨论】:

  • 请注意,C++11 别名语法也可用using MyCont = std::vector&lt;std::string&gt;;
  • @MatthieuM.:有趣的是我只适用于命名空间。
  • 它过去只适用于 C++03 中的命名空间,但在 C++11 中扩展了别名语法(您可能看到了 template &lt;typename T&gt; using MyVector = std::vector&lt;T, MyAllocator&lt;T&gt;&gt;; 示例)。
  • @MatthieuM.: 我的 C++11 跟不上速度。我仍然是一个正在慢慢学习 C++11 的 C++03 人。既然你展示了模板版本,我似乎记得讨论(但没有在实际项目中使用 C++11,大多数这些东西在我真正使用它们(几次)之前不会坚持下去)。
  • @Xlaudius:是的。但是如果您包含第二个文件而不包含停止编译的第一件事,就会出现问题。您已经介绍了文件之间的耦合,如果要使用第二个,则必须包含第一个。这不是一个好主意。坦率地说,额外的 5 个字符不应该是负担。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-02
  • 1970-01-01
  • 1970-01-01
  • 2011-07-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多