c++ - 具有共享私有(private)数据的模板函数

标签 c++ templates static private

我正在寻找以下情况下的“最佳实践”: 总的来说,两个(或多个)非成员函数之间共享私有(private)数据的常用方式有以下三种,各有优缺点:

// Example 1: using 'static' class

// HPP
namespace foo {
    class bar
    {
    private:
        static const char* const s_private;
        bar();

    public:
        static void s_method0();
        static void s_method1();
    }; /* class bar */
} /* namespace foo */

// CPP
namespace foo {
    const char* const bar::s_private = "why do I need to be visible in HPP?";

    void bar::s_method0() { std::cout << "s_method0 said: " << s_private << std::endl; }
    void bar::s_method1() { std::cout << "s_method1 said: " << s_private << std::endl; } 
} /* namespace foo */


// Example 2: using unnamed-namespace

// HPP
namespace foo { 
    void bar0(); 
    void bar1();
} /* namespace foo */

// CPP
namespace foo {
    namespace {
        const char* const g_anonymous = "why do I need external linkage?";
    } /* unnamed-namespace */

    void bar0() { std::cout << "bar0 said: " << g_anonymous << std::endl; }
    void bar1() { std::cout << "bar1 said: " << g_anonymous << std::endl; }
} /* namespace foo */


// Example 3: using static keyword in namespace-scope

// HPP
namespace foo { 
    void bar0(); 
    void bar1();
} /* namespace foo */

// CPP
namespace foo {
    static const char* const g_internal = "nobody outside this file can see me and I don't have external linkage";

    void bar0() { std::cout << "bar0 said: " << g_internal << std::endl; }
    void bar1() { std::cout << "bar1 said: " << g_internal << std::endl; }
} /* namespace foo */

我更喜欢“示例 3”,因为它尽可能接近意图。 但是现在我遇到了一些使用模板函数的问题。 “示例 1”似乎是解决此问题的唯一方法:

// HPP
namespace foo {
    class bar
    {
    private:
        static const char* const s_private;
        bar();

    public:
        template<typename T> static void s_method0() { std::cout << "s_method0 said: " << s_private << std::endl; }
        template<typename T> static void s_method1() { std::cout << "s_method1 said: " << s_private << std::endl; }
    }; /* class bar */
} /* namespace foo */

// CPP
namespace foo {
    const char* const bar::s_private = "why do I need to be visible in HPP?";
} /* namespace foo */

这不令人满意。特别是因为有其他(在本例中为方法)非成员函数应该在相同(在本例中为类)范围内,它们不需要访问此私有(private)数据。

有人知道一个优雅的解决方案吗?

感谢您的帮助。 最好的问候。

最佳答案

有点不幸的是,这是模板经常出现的问题。

但我是否可以建议您在这里过度设计?

事实是,无论您查看 Loki 代码(由 Andrei Alexandrescu 编写)还是 Boost 代码(尤其是臭名昭著的 David Abrahams),都没有人真正费心提供更好的隐私。

相反,他们只是简单地依赖于约定并使用Private 命名空间 (Loki) 或 detail 命名空间(Boost,有时使用更长且更具描述性的名称以防止冲突).

这很烦人,但在实践中你无能为力......虽然我实际上有针对你的特定问题的解决方案;)

// Evil solution!

#ifdef MY_SUPER_MACRO
#  error "MY_SUPER_MACRO is already defined!"
#endif

#define MY_SUPER_MACRO "Some string"

template <typename T> void foo() { std::cout << "foo - " MY_SUPER_MACRO "\n"; }
template <typename T> void bar() { std::cout << "bar - " MY_SUPER_MACRO "\n"; }

#undef MY_SUPER_MACRO

然后,我用一个邪恶的宏在 header 中实现了局部性:)

关于c++ - 具有共享私有(private)数据的模板函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4787223/

相关文章:

java - 每次返回对象的相同实例

c++ - 初学者 C++ - 解释类定义

c++ - “stoi”未在此范围内声明

wpf - DataGridCell.Template 样式覆盖 IsSelected 触发器

c++11可变参数编程,如何定义 vector 塔

node.js - 如何使用静态方法扩展类?

android - Kotlin:伴随对象 lateinit vars 初始化一次吗?

c++ - 类名不命名 C++ 中的类型

c++ - 后缀评估

c++ - 添加参数后“模板参数推导/替换失败”