如何通过英特尔 C++ 编译器 (ICC) 在三种方法上使用 SFINAE?
How to use SFINAE on three methods with Intel C++ Compiler (ICC)?
我正在尝试在我的一个项目中添加对 icc 的支持,但是当有两种以上的方法时,我在使用 SFINAE 时遇到了一些问题。这是问题的一个简单示例:
#include <iostream>
template<std::size_t Selector>
struct impl {
template<bool Enable = true, typename std::enable_if<Selector == 1 && Enable, int>::type = 0>
static void apply(){
std::cout << "First selector" << std::endl;
}
template<bool Enable = true, typename std::enable_if<Selector == 2 && Enable, int>::type = 0>
static void apply(){
std::cout << "Second selector" << std::endl;
}
template<bool Enable = true, typename std::enable_if<Selector == 3 && Enable, int>::type = 0>
static void apply(){
std::cout << "Big selector" << std::endl;
}
};
int main(){
impl<1>::apply();
impl<2>::apply();
impl<3>::apply();
return 0;
}
这对 g++ 和 clang++ 很有用,但无法用 icc 编译:
test.cpp(16): error: invalid redeclaration of member function template "void impl<Selector>::apply() [with Selector=1UL]" (declared at line 11)
static void apply(){
^
detected during instantiation of class "impl<Selector> [with Selector=1UL]" at line 22
test.cpp(11): error: invalid redeclaration of member function template "void impl<Selector>::apply() [with Selector=3UL]" (declared at line 6)
static void apply(){
^
detected during instantiation of class "impl<Selector> [with Selector=3UL]" at line 24
compilation aborted for test.cpp (code 2)
icc 是否有解决此问题的方法?我想避免更改太多代码,我在项目的几个地方都有这个问题。
我使用的是 icc 16.0.2.164。
谢谢
专业化是一种解决方案:
template<std::size_t Selector>
struct impl {
static void apply();
};
template<>
void impl<1>::apply(){
std::cout << "First selector" << std::endl;
}
template<>
void impl<2>::apply(){
std::cout << "Second selector" << std::endl;
}
template<>
void impl<3>::apply(){
std::cout << "Big selector" << std::endl;
}
对于问题中显示的代码,如@Jarod42 的回答所示,显式特化成员函数可能是最简单的。
当 SFINAE 基于 class 模板的参数创建 class 模板成员函数时,获得正确的代码可能很棘手。 [temp.res]/p8:
If no valid specialization can be generated for a template, and that
template is not instantiated, the template is ill-formed, no
diagnostic required.
诀窍是让 SFINAE 表达式依赖于成员函数模板的参数:
template<std::size_t Selector>
struct impl {
template<std::size_t S = Selector, typename std::enable_if<S == 1, int>::type = 0>
static void apply(){
std::cout << "First selector" << std::endl;
}
template<std::size_t S = Selector, typename std::enable_if<S == 2, int>::type = 0>
static void apply(){
std::cout << "Second selector" << std::endl;
}
template<std::size_t S = Selector, typename std::enable_if<S == 3, int>::type = 0>
static void apply(){
std::cout << "Big selector" << std::endl;
}
};
请注意,以上每个 apply()
都有一个有效的专业化。
我正在尝试在我的一个项目中添加对 icc 的支持,但是当有两种以上的方法时,我在使用 SFINAE 时遇到了一些问题。这是问题的一个简单示例:
#include <iostream>
template<std::size_t Selector>
struct impl {
template<bool Enable = true, typename std::enable_if<Selector == 1 && Enable, int>::type = 0>
static void apply(){
std::cout << "First selector" << std::endl;
}
template<bool Enable = true, typename std::enable_if<Selector == 2 && Enable, int>::type = 0>
static void apply(){
std::cout << "Second selector" << std::endl;
}
template<bool Enable = true, typename std::enable_if<Selector == 3 && Enable, int>::type = 0>
static void apply(){
std::cout << "Big selector" << std::endl;
}
};
int main(){
impl<1>::apply();
impl<2>::apply();
impl<3>::apply();
return 0;
}
这对 g++ 和 clang++ 很有用,但无法用 icc 编译:
test.cpp(16): error: invalid redeclaration of member function template "void impl<Selector>::apply() [with Selector=1UL]" (declared at line 11)
static void apply(){
^
detected during instantiation of class "impl<Selector> [with Selector=1UL]" at line 22
test.cpp(11): error: invalid redeclaration of member function template "void impl<Selector>::apply() [with Selector=3UL]" (declared at line 6)
static void apply(){
^
detected during instantiation of class "impl<Selector> [with Selector=3UL]" at line 24
compilation aborted for test.cpp (code 2)
icc 是否有解决此问题的方法?我想避免更改太多代码,我在项目的几个地方都有这个问题。
我使用的是 icc 16.0.2.164。
谢谢
专业化是一种解决方案:
template<std::size_t Selector>
struct impl {
static void apply();
};
template<>
void impl<1>::apply(){
std::cout << "First selector" << std::endl;
}
template<>
void impl<2>::apply(){
std::cout << "Second selector" << std::endl;
}
template<>
void impl<3>::apply(){
std::cout << "Big selector" << std::endl;
}
对于问题中显示的代码,如@Jarod42 的回答所示,显式特化成员函数可能是最简单的。
当 SFINAE 基于 class 模板的参数创建 class 模板成员函数时,获得正确的代码可能很棘手。 [temp.res]/p8:
If no valid specialization can be generated for a template, and that template is not instantiated, the template is ill-formed, no diagnostic required.
诀窍是让 SFINAE 表达式依赖于成员函数模板的参数:
template<std::size_t Selector>
struct impl {
template<std::size_t S = Selector, typename std::enable_if<S == 1, int>::type = 0>
static void apply(){
std::cout << "First selector" << std::endl;
}
template<std::size_t S = Selector, typename std::enable_if<S == 2, int>::type = 0>
static void apply(){
std::cout << "Second selector" << std::endl;
}
template<std::size_t S = Selector, typename std::enable_if<S == 3, int>::type = 0>
static void apply(){
std::cout << "Big selector" << std::endl;
}
};
请注意,以上每个 apply()
都有一个有效的专业化。