非专业模板中模板专业化的成员访问

Posted

技术标签:

【中文标题】非专业模板中模板专业化的成员访问【英文标题】:Member access of template specialisation in unspecialised template 【发布时间】:2015-08-01 01:33:28 【问题描述】:

以下代码编译失败(使用 clang):

template<int N>
class Foo 
    public:
        Foo() : value(N)  

        void getValue(Foo<1>& foo)
        
            value = foo.value;
        

    protected:
        int value;
;

int main(int argc, const char * argv[])

    Foo<1> fooOne = Foo<1>();

    Foo<2> fooTwo = Foo<2>();

    fooTwo.getValue(fooOne);

    return 0;

错误是main.cpp:21:15: error: 'value' is a protected member of 'Foo&lt;1&gt;'。这一切都很好。

我的问题是有没有办法让朋友使用它来工作?例如下面的代码会产生同样的错误,但我希望它会起作用。

template<int N>
class Foo 
    public:
        Foo() : value(N)  

        friend class Foo<1>;

        void getValue(Foo<1>& foo)
        
            value = foo.value;
        

    protected:
        int value;
;

我当然可以非常可怕并使用Accessing protected member of template parameter 或http://www.gotw.ca/gotw/076.htm 中的技巧。但我宁愿不要因为我可能只是在密集的事情而诉诸这种级别的黑客技术。

【问题讨论】:

【参考方案1】:

friend-ing 方法不对。 Foo&lt;N&gt; 需要成为Foo&lt;1&gt; 的朋友,因为它需要访问Foo&lt;1&gt; 的内部;你正在制作Foo&lt;1&gt;friendFoo&lt;N&gt;。为简单起见,您可以只friend所有这些:

template <int N>
class Foo 
    // mass inter-Foo friendship
    template <int > friend class Foo;

    // rest as you had before
;

【讨论】:

啊,是的...我的老朋友掌心向我打招呼了。 有什么方法可以更严格地做到这一点?那是为了确保 Foo 只是 Foo 的朋友?如果我按照自己的方式处理代码,我会将这两个类彼此分开,因为它们巧妙地做不同的事情。 @BenWhale 只需将Foo&lt;1&gt; 重命名为...Bar。如果他们做不同的事情,为什么要他们共享一个模板? 长话短说:它是复杂性质的遗留代码,而且高层很合理,不希望我在添加新错误的情况下搞得太多。这个问题与增加封装的小尝试有关,这将有助于防止对象 Foo 的进一步滥用。

以上是关于非专业模板中模板专业化的成员访问的主要内容,如果未能解决你的问题,请参考以下文章

抛出模板专业化错误的函数指针数组(包括成员函数)

如何避免“模板参数在部分专业化中无法推导”

在派生类中专门化模板成员

模板专业化 VS 函数重载

单独的 .cpp 文件中的模板类专业化

C ++模板专业化优先级。模板化专业化