【问题标题】:Can all instantiations of a class template share the same template independent member function?类模板的所有实例可以共享相同的模板独立成员函数吗?
【发布时间】:2014-12-19 04:32:42
【问题描述】:

在下面的示例中,我假设类模板函数get_count() 将有两个不同的实例化,这是多余的,因为它们不依赖于模板参数。这是真的(或优化了吗?),当涉及到某些成员函数时,有没有办法让模板的所有实例化都使用一个通用函数(可能是一些模板参数通配符,如<*>?)?

template<class T>
class A {
    private:
        T obj;
        int count;
    public:
        int get_count(); 
};

template<class T>
int A<T>::get_count() { // This function doesn't really need to
                        // depend on the template parameter.
    return this->count;
}

int main() {
    A<int> a;  //<--First template instantiation
    A<bool> b; //<--Second template instantiation
    int i = a.get_count(); //<--Could theoretically use the same code
    int j = b.get_count(); //<--
    return 0;
}

另外,如果重新排列成员变量呢?

【问题讨论】:

    标签: c++ class templates methods instantiation


    【解决方案1】:

    是的,有一种方法,它是一种使用的实现技术:

    制作一个不依赖于模板参数的基类,并将模板无关的代码放在那里。这将使实例化只进行一次。对于模板参数依赖的代码,在模板类本身做:

    class base {
       int count;
    public:
        std::size_t get_count()...
    };
    
    template <class T>
    class derived : public base {};
    

    类似的技术用于减少实现中的代码膨胀。

    【讨论】:

    • 哦,是的,没看过。只是专注于这个问题。这样就可以了。
    【解决方案2】:

    您认为所有实例化都可以对A&lt;..&gt;::get_count() 使用相同代码的假设是完全错误的。

    看看班级成员:

        T obj;
        int count;
    

    因此,模板参数T 确定了count 的偏移量,这是get_count() 返回的成员。

    无论如何,如果两个实例化碰巧产生相同的指令,编译器不会将它们合并。
    作为一个 QoI 问题,如果启用了优化,它应该是。

    有一种方法可以让多个类对一个函数使用相同的代码,而无需依赖编译器优化:
    派生自提供该功能的公共基础。

    struct A_base {
        int get_count();
    protected:
        int count;
    }
    template<class T>
    class A : A_base {
        T obj;
    };
    
    int A_base::get_count() {
        return this->count;
    }
    

    (最终,as-if-rule 占主导地位:编译器可能会复制代码以暴露优化可能性,否则无法使用。)

    【讨论】:

    • 没错,然后把他们转过来,把计数放在首位......然后他们可以共享代码:)
    • 我的回答也说明了那些成员被重新安排的情况。我也扩大了你的问题。
    • 太棒了!好的,所以如果我出于某种原因想在模板中定义我的方法,那么要走的路就像我的例子一样?
    • 是的,但你要付出代价:依赖编译器来优化它。
    • @Deduplicator 在这里提出了一个关于该主题的问题:stackoverflow.com/q/26533740/1774667
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-09
    • 2012-08-17
    • 2011-01-22
    相关资源
    最近更新 更多