SFINAE enable_if 使用 pre c++11 启用构造函数
SFINAE enable_if enable constructor with pre c++11
我的构造函数有两个不同的版本(一个用于 gpu,一个用于 cpu),但两个版本的类的其余部分几乎相同。
我想通过 SFINAE enable_if语句启用此类的 cpu 变体。
问题是,我需要在没有 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 进行编译。
建议将其作为替代解决方案。
我们可以改用标签,而不是使用 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);
}
不完全是你问的(我想有点愚蠢的解决方案),但是......如果可以接受构造函数接收必需的虚拟参数(未定义类型),则可以在第二个可选参数上激活 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");
}
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_tag
初始化data<gpu>
,但只有适当的一个会被调用。
相关文章:
- OpenCL 矢量类型:在启用 C++11 的情况下无法访问联合组件 x,y,z
- OpenCV 4.x+ 需要启用 C++11 支持编译暗网致命错误
- SFINAE enable_if 使用 pre c++11 启用构造函数
- 如何在 kali Linux 的 make 命令中启用 c++11
- 为什么即使在启用 C++11 并且我包含字符串之后,'stod'仍然没有在此范围内声明?
- 如何在 Eclipse 中启用 C++11 支持
- 如果向量是特定的长度,则使用C++11 std::enable_if来启用成员函数
- std::启用 C++11 时的矢量性能回归
- 如何为Android Studio启用C++11
- 即使启用了 C++11,静态成员初始化也不适用于 GCC
- 当使用 stdlibc++ 4.7 启用 C++11 时,clang 错误,而 gcc 编译正常
- Eclipse CDT启用c++ 11的问题
- 在Eclipse Juno ADT中启用c++ 11符号解析
- 如何在Qt Creator中启用c++ 11
- 如何在<functional>启用 C++11 的情况下在 Xcode 4.6.2 中进行编译
- clang中是否有一组已知的' c++11 '特性默认启用而不需要' -std=c++11 ' ?
- 警告:非静态数据成员初始化器只能使用-std=c++11或-std=gnu++11[默认启用]
- 通过cmake在VS 2013中启用c++ 11支持
- Android上启用c++ 11支持
- 启用 c++11 时 c++ 递归模板的奇怪行为