编译此代码:
#include <iostream>
template <int N>
struct TestClass {
template <int N2, typename std::enable_if<N2 == N, int>::type = 0>
void doAction() { std::cout << "TestClass::doAction<" << N << ">();\n"; }
};
struct HostClass : public TestClass<1>, public TestClass<2> {
};
int main(int argc, const char * argv[]) {
HostClass hostClass;
hostClass.doAction<1>();
hostClass.doAction<2>();
return 0;
}
会导致不明确的调用错误,因为doAction
同时属于TestClass<1>
和TestClass<2>
个父类。
main.cpp:33:15:在多个不同类型的基类中找到成员'doAction'
但是std::enable_if
不会禁用这种歧义吗?
修改
我认为这种含糊不清的真正原因与此问题相同:
DML statements that would have been executed one row at a time
可以通过using
关键字
#include <iostream>
template <int N>
struct TestClass {
template <int N2, typename std::enable_if<N2 == N, int>::type = 0>
void doAction() { std::cout << "TestClass::doAction<" << N << ">();\n"; }
};
struct HostClass : public TestClass<1>, public TestClass<2> {
using TestClass<1>::doAction;
using TestClass<2>::doAction;
};
int main(int argc, const char * argv[]) {
HostClass hostClass;
hostClass.doAction<1>(); // OK, compile
hostClass.doAction<2>(); // OK, compile
//hostClass.doAction<3>(); // OK, doesn't compile : "candidate template ignored: disabled by 'enable_if' [with N2 = 3]"
return 0;
}
我不知道这是@skypjack的回答是什么意思,但我还是以其替代方法让它。
答案 0 :(得分:5)
在替换后,它会(让我说) drop 这两个函数中的一个
无论如何,首先编译器必须决定你在调用doAction<1>
,然后时要使用哪个函数,它可以继续进行替换并最终抛弃所选择的函数,因为sfinae
在调用时,它们都是有效的候选者,并且调用实际上是不明确的。
请注意,正如@ Peregring-lk在评论中所建议的那样,TestClass<1>::doAction
和TestClass<2>::doAction
是放置在不同命名空间中的两个不同函数,它们不是同一函数的重载。
这实际上是误解的常见原因。
您可以轻松解决以下问题:
#include <iostream>
template <int N>
struct TestClass {
void doAction() { std::cout << "TestClass::doAction<" << N << ">();\n"; }
};
struct HostClass : public TestClass<1>, public TestClass<2> {
template<int N>
void doAction() { return TestClass<N>::doAction(); }
};
int main(int argc, const char * argv[]) {
HostClass hostClass;
hostClass.doAction<1>();
hostClass.doAction<2>();
return 0;
}