考虑这个非法代码:
template <int... Is>
struct Object {
void foo() const;
};
template <int... Js>
void Object<0, Js...>::foo() {/*Do whatever*/}
我们想在第一个模板参数为 0 时特化 foo(),假设我们也想在第二个参数为 3 且第三个 int 为 1 时特化 foo()。所以我找到了解决方案 (不确定它是否是最好的方法)如下:
#include <iostream>
template <int...> struct Foo;
template <int... Is>
struct Object {
int ID; // This member is just to illustrate the case when 'this' is needed in foo().
friend struct Foo<Is...>;
void foo() const {Foo<Is...>::execute(this);} // Pass 'this' in case it is needed.
};
template <int... Is>
struct Foo<0, Is...> {
static void execute (const Object<0, Is...>* object) {std::cout << "First int = 0, ID = " << object->ID << ".\n";}
};
template <int N, int... Is>
struct Foo<N, 3, Is...> {
static void execute (const Object<N, 3, Is...>* object) {std::cout << "Second int = 3, ID = " << object->ID << ".\n";}
};
template <int M, int N, int... Is>
struct Foo<M, N, 1, Is...> {
static void execute (const Object<M, N, 1, Is...>* object) {std::cout << "Third int = 1, ID = " << object->ID << ".\n";}
};
int main() {
Object<0,5,8,2>{4}.foo();
Object<4,3,2,5,3>{2}.foo();
Object<4,2,1>{0}.foo();
}
首先,这个解决方案好吗?接下来,如果我们尝试 Object<0,3,1,4>{8}.foo();
,问题就出现了因为规范不完整。因此,假设最早匹配的专用 int 将始终优先。所以在这种情况下 Object<0,3,1,4>{8}.foo();
由于 0,应该运行第一个特化,而 Object<9,3,1,4>{8}.foo();
由于 3,应运行第二个特化,依此类推。如何执行该规则?
最佳答案
我建议只使用 if
语句。无论如何,编译器可能会优化它们(假设您启用了优化)。
换句话说,就是做这样的事情:
template <int... Js>
void Object::foo() {
std::array<int, sizeof...(Js)> args = {Js...}; // I _think_ this is the correct syntax to dump the parameter pack into an std::array.
if(args.size() > 0 && args[0] == 0) {
// First argument is 0, do whatever.
} else {
// It's not 0, do your other thing.
}
}
您将获得几乎相同的效果,并且您的代码会更加清晰。
关于c++ - 从可变参数模板类中特化一个函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31284368/