我在C++ 11中看到了以下enable_if示例:
struct is_64_bit
{
static const bool value = sizeof(void*) == 8;
};
enable_if<is_64_bit::value, void>::type
my_memcpy(void* target, const void* source, size_t n)
{
cout << "64 bit memcpy" << endl;
}
enable_if<!is_64_bit::value, void>::type
my_memcpy(void* target, const void* source, size_t n)
{
cout << "32 bit memcpy" << endl;
}
Run Code Online (Sandbox Code Playgroud)
据我了解,根据系统架构,"my_memcpy"函数可用于32位或64位版本.但是我在编译时遇到以下错误:
error: ‘type’ in ‘struct std::enable_if<false, void>’ does not name a type
Run Code Online (Sandbox Code Playgroud)
我有点困惑,因为我认为只有32版本可用(我使用的是Linux Fedora 32位).
这个例子可能有问题吗?还是我错过了什么?
谢谢.
cyo*_*yon 10
模板template< bool B, class T = void > struct enable_if是专用的,因此它只typedef type有条件B的时间true.
你的编译器是正确的.没有的typedef type在struct std::enable_if<false, void>.只有一个typedef struct std::enable_if<true, void>.
欲了解更多信息看这里.
因此,要解决您的问题,您需要确保enable_if具有评估为B的B false永远不会被编译.您可以通过制作功能模板在SFINAE的帮助下实现这一目标my_memcpy.然后,如果编译B编译的函数模板失败,编译器将不报告错误,false并且将成功编译并使用B求值的函数true.
#include <iostream>
#include <type_traits>
using namespace std;
struct is_64_bit
{
static const bool value = sizeof(void*) == 8;
};
template<typename T>
typename enable_if<is_64_bit::value, T>::type
my_memcpy(T* target, const T* source, size_t n)
{
cout << "64 bit memcpy" << endl;
}
template<typename T>
typename enable_if<!is_64_bit::value, T>::type
my_memcpy(T* target, const T* source, size_t n)
{
cout << "32 bit memcpy" << endl;
}
Run Code Online (Sandbox Code Playgroud)
eca*_*mur 10
std::enable_if通过替换失败的原则工作不是错误(SFINAE),它指出当在实例化函数模板时发生某些类型的错误时,程序继续使用不参与重载解析的函数模板进行编译.
要使SFINAE启动,(a)必须在功能(或方法)模板上使用它,(b)它必须依赖于模板参数.您的程序在两个方面均失败.
要使enable_if依赖于模板参数,最简单的方法是添加默认参数:
template<typename T = void> typename enable_if<is_64_bit::value, T>::type
my_memcpy(void* target, const void* source, size_t n)
Run Code Online (Sandbox Code Playgroud)
但是,这通常不是合理使用的enable_if; 因为它依赖于拦截编译错误,所以它往往很昂贵.在您的情况下,模板专业化将是一个更好的主意:
#include <iostream>
template<int = sizeof(void *)> void my_memcpy(void* target, const void* source, size_t n);
template<> void my_memcpy<8>(void* target, const void* source, size_t n) {
std::cout << "64 bit memcpy" << std::endl;
}
template<> void my_memcpy<4>(void* target, const void* source, size_t n) {
std::cout << "32 bit memcpy" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
SFINAE 用于模板。您需要的是使用模板,如其他答案所述,或者只有一个编译时分支,IMO 是更合适的解决方案(而不是引入不必要的模板):
struct is_64_bit :
std::integral_constant<bool, sizeof(void*) == 8>
{};
namespace detail
{
void my_memcpy(void* target, const void* source, std::size_t n, std::true_type)
{
std::cout << "64 bit memcpy" << std::endl;
}
void my_memcpy(void* target, const void* source, std::size_t n, std::false_type)
{
std::cout << "32 bit memcpy" << std::endl;
}
}
void my_memcpy(void* target, const void* source, std::size_t n)
{
my_memcpy(target, source, n, is_64_bit());
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6302 次 |
| 最近记录: |