小编bcu*_*ing的帖子

函数的嵌套C++模板参数

我想在C++中有一个模板化函数,其中一个模板参数本身就是另一个模板参数的模板.如果这没有任何意义,请使用以下代码打印在类型T上模板化的std :: vector

template <typename T>
void print_vector(std::vector<T> &vec)
{
    for(auto v: vec)
        std::cout << v << " ";
    std::cout << std::endl;
}
...
std::vector<double> vec(5);
...
print_vector(vec);
Run Code Online (Sandbox Code Playgroud)

我想进一步推广除vector之外的STL容器的这个函数.但我不知道如何"嵌套"模板参数,以便容器在类型T上模板化.我尝试了以下但没有成功

template <typename T, template <typename TT> V>
void print_container(V<T> &con)
{
    for(auto c: con)
        std::cout << c << " ";
    std::cout << std::endl;
}
...
std::vector<double> vec(5);
...
print_container(vec);
Run Code Online (Sandbox Code Playgroud)

我确信之前已经回答了这个问题,但我找不到搜索条件来找到答案.

编辑:谢谢@ForEveR,您的回复是对的!对我的问题的所有回答都表明,没有必要将"存储"类型T模板化,以下解决方案足以满足我给出的示例:

template <typename C>
void print_container(C &con)
{
    for(auto v: con)
        std::cout << v << " ";
    std::cout << std::endl; …
Run Code Online (Sandbox Code Playgroud)

c++ templates c++11

20
推荐指数
2
解决办法
2万
查看次数

如何使用nvcc禁用编译器警告

我想禁用特定编译器警告nvcc,特别是

警告:不允许NULL引用

我正在使用的代码使用NULL引用是其中的一部分#pragma,因此无法避免.

一个理想的解决方案是nvcc在我们想要禁用警告的源文件中,但编译器标志也可以,如果存在只关闭有问题的警告.

编辑:5年前我问过这个问题,从那以后就提供了两种不同的解决方案.

下面的@ user2333829提出的第一个是使用NULL编译器标志来关闭整个文件的警告.

第二个解决方案,通过@cr_dave5年提出的问题被问之后,是一个#pragma基础的方法,可以让你关闭警告非常有针对性的方式.

多年来感谢您的反馈!

cuda pragma compiler-warnings nvcc

16
推荐指数
3
解决办法
7536
查看次数

C++ 14:使用三元表达式从constexpr中推导出(自动)返回类型

我正在使用C++ 14中的constexpr函数进行实验.以下代码计算析因是按预期工作的:

template <typename T>
constexpr auto fact(T a) {
    if(a==1)
        return 1;
    return a*fact(a-1);
}

int main(void) {
    static_assert(fact(3)==6,  "fact doesn't work");
}
Run Code Online (Sandbox Code Playgroud)

用clang编译如下:

> clang++ --version
clang version 3.5.0 (tags/RELEASE_350/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix
> clang++ -std=c++14 constexpr.cpp
Run Code Online (Sandbox Code Playgroud)

但是,当我更改fact定义以使用三元?运算符时:

template <typename T>
constexpr auto fact(T a) {
    return a==1 ? 1 : a*fact(a-1);
}
Run Code Online (Sandbox Code Playgroud)

我得到以下编译器错误:

> clang++ -std=c++14 constexpr.cpp
constexpr.cpp:12:31: fatal error: recursive template instantiation exceeded maximum depth of
      256
    return a==T(1) ? …
Run Code Online (Sandbox Code Playgroud)

c++ ternary-operator constexpr c++14

13
推荐指数
1
解决办法
1255
查看次数

在Julia中使用匿名函数的性能损失

我注意到在Julia中使用匿名函数会导致性能下降.为了说明我有两个quicksort实现(取自Julia发行版中的微观性能基准).第一种按升序排序

function qsort!(a,lo,hi)
    i, j = lo, hi
    while i < hi
        pivot = a[(lo+hi)>>>1]
        while i <= j
            while a[i] < pivot; i += 1; end
            while pivot < a[j]; j -= 1; end
            if i <= j
                a[i], a[j] = a[j], a[i]
                i, j = i+1, j-1
            end
        end
        if lo < j; qsort!(a,lo,j); end
        lo, j = i, hi
    end
    return a
end
Run Code Online (Sandbox Code Playgroud)

第二个需要一个额外的参数:一个匿名函数,可用于指定升序或降序排序,或比较更奇特的类型

function qsort_generic!(a,lo,hi,op=(x,y)->x<y)
    i, j = lo, hi
    while i < hi
        pivot = …
Run Code Online (Sandbox Code Playgroud)

performance anonymous-function julia

5
推荐指数
3
解决办法
892
查看次数

D中循环索引变量的默认类型是什么?

我已经开始学习D了,我对Andrei Alexandrescu 所着的D编程语言中提供的例子有些麻烦.由于int和ulong类型之间的转换,一些示例无法编译,其中一个我在下面概述.

我怀疑问题是由于我使用64位版本的编译器(Digital Mars 2.064.2 for 64-bit Ununtu)引起的,本书中的示例是使用32位编译器测试的.

以下代码:

#!/usr/bin/rdmd
import std.stdio;
void main(){
    int[] arr = new int[10];
    foreach(i, ref a; arr)
        a = i+1;
    writeln(arr);
}
Run Code Online (Sandbox Code Playgroud)

因以下编译器错误而失败

bcumming@arapiles:chapter1 > ./arrays.d 
./arrays.d(9): Error: cannot implicitly convert expression (i + 1LU) of type ulong to int
Failed: 'dmd' '-v' '-o-' './arrays.d' '-I.'
Run Code Online (Sandbox Code Playgroud)

我可以通过明确声明变量i为int类型来解决这个问题:

foreach(int i, ref a; arr)
    a = i+1;
Run Code Online (Sandbox Code Playgroud)

有哪些规则可以确定循环索引的默认类型在D中?是因为我使用的是64位编译器吗?

d

4
推荐指数
2
解决办法
107
查看次数

更改类型而不更改位

我想把一个堆栈变量和reinterpret cast它变成一个大小相同的无符号整数类型.例如,我可能想要获取double值并将其转换为a uint64_t,并且不会修改位.我想以通用的方式做到这一点.

如果我正在处理指针,我会使用reinterpret_cast<uint64_t*>(double_ptr).

我提出了一个解决方案,它使用了一个肮脏的黑客reinterpret_cast,并且是有效的,但它需要相当多的元编程来获得一个相当简单的结果.

问题是:有更好的方法吗?我确信有,并且我正在使这比需要更复杂.

我确实考虑过使用类型T和尺寸合适的模板化联合int_t,但这看起来甚至更黑,并且似乎与未定义的行为一起玩.

编辑我理解标准没有指定double应该是64位,如注释中所指出的那样.但是使用通用方法,我将能够获得与double相同大小的无符号整数类型,无论大小如此.

#include <iostream>

template <typename T, std::size_t S>
struct helper {};

template <typename T>
struct helper<T, 1> {
    using type = uint8_t;
};
template <typename T>
struct helper<T, 2> {
    using type = uint16_t;
};
template <typename T>
struct helper<T, 4> {
    using type = uint32_t;
};
template <typename T>
struct helper<T, 8> {
    using type = uint64_t; …
Run Code Online (Sandbox Code Playgroud)

c++ types casting c++11

1
推荐指数
1
解决办法
326
查看次数