【问题标题】:Private Class within Namespace命名空间中的私有类
【发布时间】:2013-08-23 17:56:04
【问题描述】:

我在头文件的命名空间中有一个类。该类需要模板类型,而我只想使用某些类型。下面是一个例子。

文件 a.hpp

// a.hpp
namespace a_ns {
template<class T>    
class a {
    // stuff
};
typedef a<double> a_double;
} // end of namespace
// stuff

文件 b.hpp

// b.hpp
#include <a.hpp>
namespace b_ns {
    typedef a_ns::a_double b;
}

文件 main.cpp

// main.cpp
#include "b.hpp"
int main() {
    b_ns::b my_b; // <<<--- I LIKE this!
    a_ns::a<float> my_a_which_is_not_allowed; // <<<--- I DO NOT LIKE THIS THOUGH! D:
}

所以你可以从这个久违的例子中看到,最终目标是不允许最终用户声明 class afloat 作为类型名,并且只能使用预定义的具有特定类型的类,由 typedef a&lt;double&gt; a_double; 声明。

我认为上面的这个例子会允许这样做,但是我错了,因为我可以像上面一样创建一个a&lt;float&gt;,因为我包含了b.hpp,而它又包含了a.hpp!所以你看到了问题! (希望?)

如果可能的话,可能有一个简单的解决方案。

【问题讨论】:

    标签: c++ class namespaces typedef private


    【解决方案1】:

    如果你只想能够使用类型别名而不是直接使用a,你可以把它放到一个用户应该知道不要使用的实现命名空间中:

    namespace a_ns {
    
    namespace detail {
        template<class T>        
        class a {
            // stuff
        };
    }
    
    typedef detail::a<double> a_double;
    } // end of namespace
    

    现在任何东西都可以使用a_double,但是要直接使用a,你的detail 命名空间必须被挖掘,这被普遍认为是一件坏事。如果用户决定要这样做,他们已经放弃了避免麻烦,您不应该采取额外措施来阻止他们伤害自己。

    【讨论】:

    • 其实我很喜欢这个——我怕没有办法战胜麻烦的程序员。
    • @DieterLücking,一旦你克服了他们必须故意把自己挖进洞里的事实,你就会开始减少对防止它的担心。如果他们想把自己搞砸,就让他们吧。如果那里有什么东西可以真正帮助他们,至少现在他们不需要破解。
    • 或者正如 Herb Sutter 所说:防御墨菲,而不是马基雅维利
    • 嗯,是的,我很喜欢这个。这并不完全是无懈可击的,但正如你所说“如果他们故意搞砸自己......”猜猜这是一个好的解决方案(+1)
    • @EdwardBird 它被用于整个 Boost 库。一旦转移到模板库,就真的无法阻止用户获取源代码并定义他们想要的任何内容。
    【解决方案2】:

    这是使用 static_assert 的方法

    #include <type_traits>
    template <typename T>
    class X
    {
      T i;
      static_assert(!std::is_same<float,T>::value,"Don't use floating point");
    };
    
    
    
    int main()
    {
        X<int> a;
        //X<float> b; fails at compile time
        return 0;
    }
    

    只要变量不是 const 或 volatile,这将起作用

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-29
      • 2021-01-02
      • 2012-05-27
      • 2012-08-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多