Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::启用_if类型检查_C++_C++11_Templates_Typechecking - Fatal编程技术网

C++ std::启用_if类型检查

C++ std::启用_if类型检查,c++,c++11,templates,typechecking,C++,C++11,Templates,Typechecking,我正在尝试编写一个函数,可以将T2类型的缓冲区转换为T1类型的缓冲区。这个函数的大部分代码都非常类似于C,因此我必须接受指向缓冲区的原始指针。缓冲器包含数字样本。对于浮点缓冲区float、double等,可能的最小值为-1.0,最大值为1.0。对于整数类型,示例跨越类型的范围。例如,int16_t示例从-32768运行到32767。因此,除了类型转换之外,还需要进行更多的转换,通常需要使用一个比例因子进行乘法,以使样本进入正确的范围 在过去,我遇到过为每种可能的样本类型编写专门转换的库。我会坦白

我正在尝试编写一个函数,可以将T2类型的缓冲区转换为T1类型的缓冲区。这个函数的大部分代码都非常类似于C,因此我必须接受指向缓冲区的原始指针。缓冲器包含数字样本。对于浮点缓冲区float、double等,可能的最小值为-1.0,最大值为1.0。对于整数类型,示例跨越类型的范围。例如,int16_t示例从-32768运行到32767。因此,除了类型转换之外,还需要进行更多的转换,通常需要使用一个比例因子进行乘法,以使样本进入正确的范围

在过去,我遇到过为每种可能的样本类型编写专门转换的库。我会坦白承认我来自一个嵌入式背景,我通常会这样做,我正在尝试学习更多现代的C++技术,而不仅仅是用类来处理语言C,但是我可以看到这种方法会导致大量的代码被复制粘贴,只是稍微编辑。 到目前为止,我认为我的模板化方法似乎是可行的,但如果在编译时我希望编译器在有人试图转换不用于示例的类型时出错,我希望使用std::enable_强制执行类型检查。到目前为止,我的代码复制如下

template <class T>
struct is_sample_type : std::integral_constant <
    bool,
    (std::is_floating_point<T>::value || std::is_integral<T>::value)> {};

template <typename T1, typename T2>
void convertSamples(T1* const dst, const T2* const src,
                    const size_t num_samples, const double scalar) {
  if ((!is_sample_type<T1>::value) || (!is_sample_type<T2>::value))
    throw std::invalid_argument("Invalid sample type passed in.");
  if (std::is_same<T1, T2>::value) return;  // nothing to convert

  // Do conversion...
}
我有几个问题:

如何转换convertSamples中的逻辑,以便在编译时使用std::enable_if执行检查?如果传入的类型相同,或者其中一个不是用于示例的类型,我希望在编译时出错。我已经尝试了很多例子,但是语法对我来说还是陌生的

对于stdint.h中定义的整数类型,std::is_integral是否返回true?我想这是真的,因为这些只是别名

编译器在后台做什么来填充类型?这是什么时候发生的?也就是说,我尝试使用OpenMP使用SIMD指令执行转换步骤,因此我希望在完成任何其他优化之前选择模板类型

答复:

非常简单:

static_assert(is_sample_type<T1>::value && is_sample_type<T2>::value), "Please use sample types");
是,返回true。看

函数是为特定类型创建的,我们称之为“模板已实例化”,然后进行正常优化


这里有一种方法可以在编译时确定输入是否匹配需求,以及它们是否需要转换,或者是否假定相同的类型意味着没有转换。我将您的元函数IsSample更改为使用布尔模板变量,因为我认为它更干净

第一个例子,我使用函数重载来处理src和dest都是相同类型的情况。当它们是时,该函数可以noop,当它们不是时,您可以转换。这使得它成为编译时if而不是运行时if

template <typename T>
constexpr bool is_sample = std::is_floating_point<T>::value || std::is_integral<T>::value;

template <typename T1, typename T2,  typename=std::enable_if_t<is_sample<T1> && is_sample<T2>>>
void convertSamples(T1* dst, const T2* src, size_t num_samples, double scalar) {
    std::cout << "converting...\n";
}

template <typename T,  typename=std::enable_if_t<is_sample<T>>>
void convertSamples(T* dst, const T* src, size_t num_samples, double scalar) {
    std::cout << "NOT converting (noop)\n";
}
您还可以方便地使用c++17 if constexpr合并这些函数,该函数与上面的函数大致相同,但只包含一个函数

template <typename T1, typename T2, typename = std::enable_if_t<is_sample<T1> && is_sample<T2>>>
void convertSamples(T1* dst, const T2* src, size_t num_samples, double scalar) {
    if constexpr (std::is_same_v<T1, T2>) {
        std::cout << "not converting\n";
        return;
    }

    std::cout << "converting\n";
}

谢谢你的快速回答。我非常关注enable_,如果我完全忘记了static_断言的话。