小编Adr*_*ian的帖子

退出函数堆栈而不退出shell

我正在编写一个脚本然后遇到了一个奇怪的问题.如果我发来一个包含一堆函数的脚本,这些函数可以调用一个输出字符串然后退出的错误函数,它将退出我的shell.我知道为什么会这样做.这是因为函数调用与调用者处于相同的进程空间中(至少它在bash中),因此函数中的退出使用提供的退出代码终止当前进程.例:

error()
{
  echo $1
  exit 1
}

fn()
{
  if [ $# == 0 ]; then
    error "Insufficient parameters."
  fi
  # do stuff
}

$ fn
Insufficient parameters.
[shell terminates]
Run Code Online (Sandbox Code Playgroud)

所以我的问题是,我可以退出函数堆栈中的所有函数而不终止当前的shell并且不生成新的子shell吗?

谢谢

bash shell function exit

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

为什么标准不允许在模板参数列表中初始化常量依赖类型?

在这篇文章的答案" (部分)专门化依赖类型的非类型模板参数 "中,它指出:

与专用非类型参数对应的模板参数的类型不应取决于特化的参数.[例如:

template <class T, T t> struct C {};
template <class T> struct C<T, 1>; // error

template< int X, int (*array_ptr)[X] > class A {};
int array[5];
template< int X > class A<X,&array> { }; // error
Run Code Online (Sandbox Code Playgroud)

- 末端的例子]

我的问题是为什么这个限制在这里?至少有一个用例,我发现这个限制干扰了编写干净的代码.例如

template <typename T, T*>
struct test;

template <typename T>
struct test<T, nullptr> // or struct test<T, (T*)nullptr>
{
};

template <typename R, typename...ARGs, R(*fn)(ARGs...)>
struct test<R(ARGs...), fn>
{
};
Run Code Online (Sandbox Code Playgroud)

虽然我不确定是否还有其他案例表明基于类型的常量是一个超出没有任何意义的问题.

任何人都有理由说明为何如此?

c++ templates template-meta-programming c++11 c++14

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

是否可以将lambda函数用于模板参数?

我正在查看std :: unordered_map并看到如果我想使用字符串作为键,我必须创建一个包含仿函数的类.

出于好奇,我想知道是否可以使用lambda来代替这个.

这是工作原创:

struct hf
{
  size_t operator()(string const& key) const
  {
    return key[0];  // some bogus simplistic hash. :)
  }
}

std::unordered_map<string const, int, hf> m = {{ "a", 1 }};
Run Code Online (Sandbox Code Playgroud)

这是我的尝试:

std::unordered_map<string const, int, [](string const& key) ->size_t {return key[0];}> m = {{ "a", 1 }};
Run Code Online (Sandbox Code Playgroud)

失败时出现以下错误:

exec.cpp: In lambda function:
exec.cpp:44:77: error: ‘key’ cannot appear in a constant-expression
exec.cpp:44:82: error: an array reference cannot appear in a constant-expression
exec.cpp: At global scope:
exec.cpp:44:86: error: template …
Run Code Online (Sandbox Code Playgroud)

c++ lambda c++11

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

有没有一种方法可以将指针转换为数组类型?

在C++中,C数组在语法上有点难以理解,并且可能需要一些时间来习惯.虽然1D数组衰减到指针:

void fn1(int x[2]) {}
void fn2(int*x) {}
Run Code Online (Sandbox Code Playgroud)

fn1()fn2()具有相同的功能签名.

数组实际上有一个类型,包括数组中有多少个元素.如:

void fn(int (&)[2]) {}
Run Code Online (Sandbox Code Playgroud)

fn() 只接受2元素的int数组.

事实是,我只能看到固定数量的元素的数组只能由具有该签名的堆栈,文件范围或结构/类分配生成:

int twoElementArray[2];
Run Code Online (Sandbox Code Playgroud)

如果我要在堆上动态分配它,我似乎无法获得相同的签名.我以为我可能会施展它,但没有成功:

int (&array)[2] = reinterpret_cast<int(&)[2]>(new int[2]); // FAIL!
Run Code Online (Sandbox Code Playgroud)

有关如何实现这一点的任何想法吗?

 


编辑:虽然我选择了一个答案,但它实际上并没有投出任何东西,但是使用了一种绝对更好的方法然后再进行投射(如果不需要IMO,最好不要施放).但是,它在技术上没有回答这个问题,因为问题是否有"一种指向数组类型的指针?" 答案是肯定的.

int (&array)[2] = *reinterpret_cast<int(*)[2]>(new int[2]); // SUCCESS!
Run Code Online (Sandbox Code Playgroud)

请注意,我不一定建议这样做,但它确实回答了这个问题.如果我需要将指针转换为数组类型,那将是如何做到的.阅读所选答案以获得更好的解决方案operator new[].

c++ c++11

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

有没有像std :: size()这样的函数?

任意给定类型T的内置阵列X,也有功能std::begin()std::end()我可以打电话,但为什么是不是有std::size()?似乎奇怪没有那个.

我可以使用std::end(x)-std::begin(x),但仍然std::size(x)会更好.

是的,我知道这些std::vectorstd::array课程.这只是一个问题,为什么STL中还没有这样简单的东西.

c++ c++11

12
推荐指数
2
解决办法
4154
查看次数

如何从PNG创建图像列表?

我在这里看到你可以创建一个透明的图像列表.它的工作......有点儿.

我用它来创建列表控件的图像列表.结果有点令人失望:

实际列表图像的视图 列表图像的视图

左边的那个是它应该看起来的样子.右边的那个是列表控件如何显示它.看起来它只是试图使用alpha作为掩模,并且尝试通过抖动来近似任何混合区域.有没有办法让这个更好,以便我得到一个真正的alpha混合图像?

如果这有任何不同,这是来源:

class CDlg : public CDialog
{
    DECLARE_DYNCREATE(CDlg)

public:
    CDlg(CWnd* pParent = NULL);   // standard constructor
    virtual ~CDlg();

    // Dialog Data
    enum { IDD = IDD_BS_PRINT };
    CGdiPlusBitmapResource m_pBitmap;

protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
    virtual BOOL OnInitDialog();

    DECLARE_MESSAGE_MAP()
public:
    CListCtrl m_printOptions;
};

BOOL CDlg::OnInitDialog()
{
    __super::OnInitDialog();

    m_pBitmap.Load(IDB_RIBBON_HOMELARGE, _T("PNG"), AfxGetResourceHandle());
    HBITMAP hBitmap;
    m_pBitmap.m_pBitmap->GetHBITMAP(RGB(0, 0, 0), &hBitmap);

    CImageList *pList = new CImageList;
    CBitmap bm;
    bm.Attach(hBitmap);
    pList->Create(32, 32, ILC_COLOR32, 0, 4);
    pList->Add(&bm, RGB(255, 0, 255)); …
Run Code Online (Sandbox Code Playgroud)

winapi mfc

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

是否可以使用带有容器的移动操作的类型?

在解释与同事对对象的移动操作时,我基本上说移动操作不应该在容器中抛出异常,因为如果移动操作失败,则无法可靠地恢复原始对象.考虑到这一点,我想知道这是不是正确的,并且如果一个移动操作确实抛出,它可以将原始对象恢复到它的原始状态.

这样做的原因是,如果一个对象可以抛出,那么它将不会因为复制或将包含的对象从旧地址移动到新地址而抛出,而是在无法获取资源时抛出.所以所有的原始信息都应该存在.如果是这种情况,那么编译器是否应该无法反转它为重建原始对象所做的操作?

操作可能是一种方式,比如移动一个整数,但在这种情况下它可能只是终止应用程序,也许如果开发人员想要避免单向操作可以使用交换方法.

这只能在默认移动运算符上实现,就像有任何其他逻辑一样,编译器可能很难进行反向部分变换.

我是否过于简化了事情?有没有我遗漏的东西,如果没有非投掷移动构造函数/运算符,容器不会移动对象?

c++ stl c++11 c++14 stdmove

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

这是在C++ 11中将一个std :: vector的内容移动到另一个的结尾的最有效方法吗?

我当时认为vector::insert()std::copy()命令需要额外的分配.但是,如果我push_back()是一个新创建的元素,那么swap()我认为只要包含的类型没有使用默认构造函数分配,这将减少任何分配.

我的问题实际上是针对std::vectors类型的std::string,但应该适用于此处所述的其他包含类型:

template <typename T>
void appendMove(std::vector<T>& dst, std::vector<T>& src)
{
    dst.reserve(dst.size() + src.size())
    for(std::vector<T>::iterator it = src.begin(); it != src.end(); ++it)
    {
        dst.push_back(std::vector<T>());
        std::swap(dst.end()[-1], *it);
    }
}
Run Code Online (Sandbox Code Playgroud)

我对么?我错过了什么吗?也许还有更好的方法吗?

c++ algorithm c++11

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

有没有一种方法可以检测当前成员函数是在左值还是右值上运行?

限定符是一种基于对象上下文重载函数的好方法。这样的限定词是constvolatile。但是,为它们编写代码很烦人,因为它们通常是代码的重复,因为cv限定符至少由传播this。这样,我们可以使用传播技巧并借助auto或来使整个函数(无cv限定词)完全相同decltype(auto)

例如:

struct X {
  int m_i = 0;

  auto& i()                &  { return m_i ; } // returns int                &
  auto& i()       volatile &  { return m_i ; } // returns int       volatile &
  auto& i() const          &  { return m_i ; } // returns int const          &
  auto& i() const volatile &  { return m_i ; } // returns int const volatile &
};
Run Code Online (Sandbox Code Playgroud)

尽管很烦人,但至少我们可以看到,这将在使用相同代码的所有上下文中起作用,从而最大程度地减少了错误。

但是,使用可用于指定成员函数的新的左值/右值限定符,this不会传播该函数是在左值还是右值的对象上调用的。如果说我想这样做,这将导致必须对该函数进行些微改动: …

c++ c++17

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

尝试克隆存储库但行尾错误

我的电脑上有 cygwin 和 msysgit。我正在尝试使用以下命令克隆 vim 包的存储库:

cd ~/.vim/bundle
git clone https://github.com/jelera/vim-javascript-syntax.git
Run Code Online (Sandbox Code Playgroud)

但是,当我运行 vim 时,它失败,报告错误E488: Trailing characters。这似乎是由行结尾CRLF而不仅仅是 引起的LF,这在我替换它们时得到确认。

当然,手动替换它们不是我想要的。我宁愿让 git 为我做这件事。但是,由于我使用我的计算机在 Windows 平台上进行开发,因此我不想修改任何全局设置。

是否有命令行开关可以让 git cloneLF EOLs只使用一个 repo ?

git cygwin msysgit

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