【问题标题】:C++ policy classes and namespacesC++ 策略类和命名空间
【发布时间】:2013-09-29 17:23:33
【问题描述】:

我已经实现了一个基于策略的类。目前,类模板及其策略类在名为实用程序的命名空间中声明。

我面临的问题是生成的代码过于冗长。客户端代码如下所示:

utility::MyTool<utility::AFirstPolicy, utility::ASecondPolicy>
my_function(utility::MyTool<utility::AnotherFirstPolicy, utility::AnotherSecondPolicy>);

如您所见,可读性不强。我想从以下方面获得更接近的信息:

MyTool<AFirstPolicy, ASecondPolicy>
my_function(MyTool<AnotherFirstPolicy, AnotherSecondPolicy>);

我想知道在这种情况下有什么好的做法。这是我能想到的:

类型定义

最明显的解决方案。对我来说不是很方便,因为政策可能因功能而异,会带来有关功能使用的重要信息。我希望它们直接出现在函数原型中。此外,它在多个命名空间中引入了许多类型名称。

使用指令

在我的文件中放一个using namespace utility;using utility::MyTool; using utility::AFirstPolicy; 等。

该工具经常用于其他命名空间的头文件中,这使得 using-directives 不太适合。

全局命名空间中的策略类

我不喜欢这种方法,尤其是因为策略类通常具有仅在其上下文中才有意义的模糊名称。

把东西当做

#define MY_TOOL(pcy1, pcy2) utility::MyTool<utility::##pcy1, utility::##pcy2>

将之前的代码转换成

MY_TOOL(AFirstPolicy, ASecondPolicy)
my_function(MY_TOOL(AnotherFirstPolicy, AnotherSecondPolicy));

我不确定这是否更具可读性。它仅适用于固定数量的策略(我的情况是:始终为 2,无默认设置),如果策略类本身采用模板参数,则它不起作用。

您会向我推荐之前的哪些方法?有“最佳实践”吗?另一个想法?

【问题讨论】:

    标签: c++ macros namespaces using policy


    【解决方案1】:

    如果你有my_function(utility::MyTool&lt;...&gt;),那么我会说my_function属于类模板utility::MyTool&lt;...&gt;的接口。也就是说my_function本身就属于namespace utility

    这意味着您可以以所需的简写形式编写代码:

    namespace utility {   
        typedef MyTool<AFirstPolicy, ASecondPolicy> SomeTool;
        my_function(SomeTool);    
    }
    

    您可以在 Herb Sutter 的旧专栏 "What's In a Class" 中阅读有关接口和命名空间的更多信息。

    请注意,即使您想通过 namespace utility 中的类使用其他命名空间中的函数,您仍然可以重新打开该命名空间并在此处定义策略类并执行类似的操作

    // SomeHeader.hpp
    namespace bla {
       // your classes and functions
    }
    
    // reopen namespace utility
    namespace utility {   
        typedef MyTool<AFirstPolicy, ASecondPolicy> SomeTool;
    }
    
    namespace bla {
        typedef utility::SomeTool BlaTool; // or using-declaration
        my_function(BlaTool);
    }
    

    这当然比在实用程序命名空间中定义my_function 更冗长,但至少您可以组装所有不同的策略而无需过多输入。

    【讨论】:

    • 感谢您的链接以及您重新打开命名空间utility 的建议。在我的例子中,my_function 不是类模板 utility::MyTool 接口的一部分,它是客户端代码,所以我将不得不使用 typedef,可能重新打开命名空间 utility 以减少冗长。跨度>
    • @ChristopheFuzier 好的,很高兴能帮上忙!
    猜你喜欢
    • 1970-01-01
    • 2016-04-11
    • 2011-06-14
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    • 2018-02-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多