c++ - 实例化多个类型的成员函数模板

标签 c++ templates instantiation c++03 explicit-instantiation

我有几个带有模板化成员函数的类和它们将使用的预定义类型列表 ( Wandbox link :

// main.cpp:
#include "class.h"

int main(int argc, char** argv) {
    A a;
    a.foo(5);
    a.foo(5.);
    B b;
    //b.bar(1,2,3,4); b.bar(1,2,3.,4);
    return 0;
}

// class.h
#pragma once

struct A {
    template<typename T> void foo(T x);
};
struct B {
    template<typename T> void bar(int p1, int p2, T x, int p3);
};


// class.cpp
#include <iostream>
#include "class.h"

template<typename T> void A::foo(T x) {
    std::cout << x << std::endl;
}

// explicit, but very verbose
// template void A::foo(int);
// ...

template<typename T> void ignore(T fn) {/* Use fn? */}

template<class Class>
void instantiate(Class) {
    // List all types the function should be instantiated for here
    ignore(&Class::template foo<int>);
    ignore(&Class::template foo<double>);
}

// works, instantiates A::foo<int> and A::foo<double>
template void instantiate(A);
// How to pass B::foo and additional parameters?
// template void instantiate(B);

键入每个要实例化的成员函数和类型的组合是可行的,但它有几个缺点:

  • 这很乏味
  • 必须输入带有每个参数的整个函数签名,并且
  • 必须在几个地方进行函数签名更改
  • 必须为每个成员函数添加一个类型到列表

我上面的解决方法适用于我测试过的大多数旧编译器(C++03 兼容性将是一个巨大的优势),但我不确定是否允许智能编译器删除未使用的参数和函数实例化。

对于常规函数,有workarounds ,但据我所知,它们不适用于成员函数。

如何更改我的实例化 函数以同时接受成员函数和其他参数?

最佳答案

经过多次尝试和错误后,我发现即使启用了优化也能正常工作(Wandbox):


// main.cpp as above

// class.h
#pragma once

// Create instantiations for templated functions by keeping their addresses
// and therefore forcing the compiler to keep their object code
// attribute((unused)) silences the clang/gcc warning
template <typename T> void ignore(T t) {static __attribute__((used)) T x = t;}

struct A {
    template<typename T> void foo(T x);
    template<typename T> friend void instantiate(T); // let instantiate call the helper function in case it's private
    // helper function that instantiates all member functions
    template<typename T> void helper() { ignore(&A::foo<T>); }
};
struct B {
    template<typename T> void bar(int p1, int p2, T x, int p3);
    // same procedure as above
    template<typename T> friend void instantiate(T);
    template<typename T> void helper() { ignore(&B::bar<T>); }
};


// class.cpp
#include 
#include "class.h"

template void A::foo(T x) {
    std::cout  void B::bar(int, int, T, int) {}

template
void instantiate(Class) {
    // List all types the function should be instantiated for here
    ignore(&Class::template helper);
    ignore(&Class::template helper);
}

template void instantiate(A);
template void instantiate(B);

为了避免更复杂的模板魔术,我添加了一个由 template<typename T> void helper() 实例化的模板函数 ( instantiate )函数,其中列出了要实例化的函数的所有所需类型。

之后,template void instantiate(A)将实例化 A::helper 中列出的所有成员函数.

关于c++ - 实例化多个类型的成员函数模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52181219/

相关文章:

c++ - 在Qt主窗口右下角放置弹出窗口

c++ - 如何比较限制小数位的 double 值?

C++ 作业 - 二叉搜索树帮助

c++ - memset 和 struct 以及 getter/setter

c++ - 将模板化函数限制为基本类型和派生类型?

actionscript-3 - as3 {} 与新对象

java - 抽象类 NumberFormat - 对 getInstance() 非常困惑

c# - 我需要帮助从单个方法和类实例化多个对象

c++ - 从 xlC 的模板函数问题中查找静态函数

templates - Magento 电子邮件模板位置?