我有几个带有模板化成员函数的类和它们将使用的预定义类型列表 ( 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/