我有两个不同版本的构造函数(一个用于gpu,一个用于cpu),但两个版本的其余版本几乎相同。
我想通过SFINAE enable_if语句启用此类的cpu-variant。
问题是,我需要在没有C ++ 11和clang ++的情况下编译它。
以下代码正常运行,但它会产生五个警告:
warning: default template arguments for a function template are a C++11
extension [-Wc++11-extensions]
有没有办法,使用sfinae而不需要用标准C ++ 11编译c ++代码而没有c ++ 11警告?
以下是代码:
#include <iostream>
enum arch_t{cpu, gpu};
template<bool B, class T=void>
struct enable_if {};
template<class T>
struct enable_if<true, T> { typedef T type; };
template<typename T1, arch_t arch>
class data {
public:
template<arch_t a=arch, typename enable = typename enable_if<a==cpu, void>::type, typename tmp = enable>
data(void)
{
std::cout << "-CPU()" << std::endl;
}
template<arch_t a=arch, typename = typename enable_if<a!=cpu, void>::type>
data(void)
{
std::cout << "-GPU()" << std::endl;
}
};
int main()
{
data<int,gpu> gpu_data;
data<int,cpu> cpu_data;
}
预期(也是实际)输出: -GPU() -CPU()
我使用clang ++ - 3.8进行编译。
答案 0 :(得分:1)
建议将其作为替代解决方案。
我们可以使用标签代替SFINAE。这里,标签是一个空结构,其名称作为一条信息(标签)。然后我们可以使用标记重载函数(包括构造函数),因为它是一个类型。所以在这种情况下我们可以有类似
的东西struct cpu_arch_t {} cpu_arch;
struct gpu_arch_t {} gpu_arch;
template<typename T1>
class data {
public:
data(cpu_arch_t)
{
std::cout << "-CPU()" << std::endl;
}
data(gpu_arch_t)
{
std::cout << "-GPU()" << std::endl;
}
};
然后我们可以像
一样使用它int main()
{
data<int> gpu_data(gpu_arch);
data<int> cpu_data(cpu_arch);
}
答案 1 :(得分:1)
不完全是你提出的问题(我想是一个有点愚蠢的解决方案)但是......如果你能接受你的构造函数接收一个必需的伪参数(未定义类型),你可以在第二个可选参数上激活SFINAE。
以下是一个工作示例
#include <iostream>
enum arch_t{cpu, gpu};
template <bool B, typename T = void>
struct enable_if
{ };
template <typename T>
struct enable_if<true, T>
{ typedef T type; };
template <typename T1, arch_t arch>
class data
{
public:
template <typename T>
data (T const &, typename enable_if<arch==cpu, T>::type * = 0)
{ std::cout << "-CPU()" << std::endl; }
template <typename T>
data (T const &, typename enable_if<arch!=cpu, T>::type * = 0)
{ std::cout << "-GPU()" << std::endl; }
};
int main ()
{
data<int,gpu> gpu_data(0);
data<int,cpu> cpu_data("abc");
}
答案 2 :(得分:0)
id, title
您必须使用enum arch_t{cpu, gpu};
template<arch_t, arch_t>
struct arch_tag { };
template<arch_t arch>
class data {
private:
public:
data(arch_tag<cpu, arch>) {
std::cout << "-CPU()" << std::endl;
}
data(arch_tag<gpu, arch>) {
std::cout << "-GPU()" << std::endl;
}
};
struct data_tag:arch_tag<cpu, cpu>, arch_tag<gpu, gpu> {};
int main(){
data<cpu> c = data_tag();
(void)c;
data<gpu> g = data_tag();
(void)g;
}
初始化data<gpu>
,但只会调用相应的一个。