实例化多种类型的成员函数模板
Instantiate member function templates for multiple types
我有几个类,其中包含模板化的成员函数和预定义的类型列表,它们将与之一起使用(Wandbox链接:
// 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 兼容性将是一个巨大的优势(,但我不确定是否允许智能编译器删除未使用的参数和函数实例化。
对于常规函数,有一些解决方法,但据我了解,它们不适用于成员函数。
如何将我的instantiate
函数更改为也接受成员函数和其他参数?
经过多次尝试和错误,我发现了即使启用了优化也可以工作的东西(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++:递归成员函数模板
- C++成员函数模板将成员函数指针作为模板参数
- 类和成员函数模板专用化出错
- 调用类模板的成员函数模板
- 课堂中成员函数模板的明确实例
- 专用和/或重载具有可变参数的成员函数模板
- 具有可变参数的类成员函数模板部分专用化
- 将 PIMPL 习惯用法与成员函数模板一起使用(无需预先了解所有可能的数据类型)
- 澄清了使用 enable_if 的成员函数模板专用化
- 是否可以从指向成员函数模板参数的指针推断类类型
- 成员函数模板推演指南或其他方法让编译器知道如何调用函数
- 成员函数模板不会在 clang 上编译,但在 GCC 上编译
- 类模板的成员函数模板找不到定义,尽管存在显式实例化。不链接
- 成员函数模板参数的部分专业化
- 在C++中创建成员函数模板专用化
- 要求派生类提供成员函数模板
- 实例化错误后成员函数模板的专业化,以及成员函数的顺序
- 使用提升::函数的成员函数模板