小编Ita*_*iwa的帖子

在条件运算符中使用对象两次是否会产生UB?

正如我所了解的那样,条件运算符(三元运算符“?”)保证了其操作数的求值顺序,我想知道是否向变量分配了?在两个表达式之一中使用该变量的返回值。是否成为UB。这是我所拥有的:

我编写了这个程序,尝试根据字符串是否str包含有效的数字字符将字符串转换为整数,例如:+-.0123456789,因此我在一个表达式中使用了std::stoiwith std::string::find_first_of和conditional运算符:

std::string str = "a^%^&fggh67%$hf#$";
std::size_t pos = 0;
auto val = (((pos = str.find_first_of("0123456789.+-")) != std::string::npos) ?
    std::stoi(str.substr(pos)) : -1);

std::cout << val << std::endl; // 67

str = "a^%^&fggh__#$!%$hf#$";
pos = 0;
val = (((pos = str.find_first_of("0123456789.+-")) != std::string::npos) ?
    std::stoi(str.substr(pos)) : -1);

std::cout << val << std::endl; // -1
Run Code Online (Sandbox Code Playgroud)

正如你所看到的一段代码看起来做工精细,我知道,如果值-1是在无意中发现str,我们不知道是否val拥有-1成功运作或失败(?运营商)的。但是我只想知道我编写的这段代码是否具有UB?

  • 感谢在上一个主题UB中指导我的成员,我已经将其更正。

c++ conditional-operator sequence-points

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

如何阅读复杂的类型?

我知道使用类型别名和 typedef 使代码可读性强、不易出错且易于修改。但是在这个例子中,我想知道这个复杂的类型:

#include <iostream>
#include <typeinfo>

char ( * (* x() )[] )();

int main(){

    std::cout << typeid(x).name() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

正如经验法则所说,我从内到外阅读它,但我觉得它太混乱了。

有人可以帮助我如何阅读吗?

GCC的输出:

FPA_PFcvEvE
Run Code Online (Sandbox Code Playgroud)

c++ function-pointers array-pointer

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

为什么 C++ 链接器不会抱怨缺少这些函数的定义?

我写了这段代码:

// print.h
#pragma once

#ifdef __cplusplus
#include <string>

void print(double);
void print(std::string const&);
extern "C"

#endif

void print();
Run Code Online (Sandbox Code Playgroud)

以及源文件:

// print.cxx
#include "print.h"
#include <iostream>

void print(double x){
  std::cout << x << '\n';
}

void print(std::string const& str){
   std::cout << str << '\n';
}

void print(){
   printf("Hi there from C function!");
}
Run Code Online (Sandbox Code Playgroud)

以及驱动程序:

// main.cxx
#include "print.h"
#include <iostream>

int main(){

  print(5);
  print("Hi there!");
  print();

  std::cout << '\n';
}
Run Code Online (Sandbox Code Playgroud)

当我编译时:

gcc -c print.cxx && g++ print.o main.cxx -o prog …
Run Code Online (Sandbox Code Playgroud)

c c++ external-links

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

Windows中的变量类型

只要存在不同大小的不同变量类型,为什么windows使用宏和移位运算符将2个值映射到一个变量中,例如:

这是win32 windows程序的示例:

//...
case WM_COMMAND:
{
    switch(LOWORD(wParam))
    {
        case IDC_LISTBOX:
        {
            switch(HIWORD(wParam))
            {
                //handle message
            }
        }
        break;
    }
}
break;
Run Code Online (Sandbox Code Playgroud)

简单地说为什么windows不使用两个类型的短变量?或者这有特权吗?

感谢你们

c++ windows winapi

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

如何从commnd提示符下将字符`^`传递给我的程序?

我有一个关于计算器的简单示例:

  • 输入第一个操作数,然后输入运算符。如果运算符是一元,则无需输入第二个。因此,打印结果,例如:如果一个数字不需要第二个操作数,则打印平方。

  • 输入可以从命令提示符传递到程序中,否则在程序从输入流启动之后。

  • 我想将输入作为参数传递给程序的原因是我有时想从命令提示符处调用程序,所以我可以发出:calc 57 + 12+输入:我得到69。

  • 该程序运行良好,但是在我使用的平方运算符中,我^可以从输入流(std :: cin)中使用它,但是如果我通过命令提示符传递它,我将无法执行!

    int main(int argc, char* argv[]){
    
        int a = 0;
        int b = 0;
        char op = '\0';
    
        if(argc < 2){
            std::cout << "a: ";
            std::cin >> a;
            std::cout << "op: ";
            std::cin >> op;
    
            switch(op){
                case '^':
                    std::cout <<  a << " ^2 " << " = " 
                        << a * a << std::endl;
                break;
                case '+':
                    std::cout << "b: ";
                    std::cin >> b;
                    std::cout << …
    Run Code Online (Sandbox Code Playgroud)

c++ argv argc

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

如何将std :: lower_bound与std :: map一起使用?

我有这个问题:

我有一个std::map代表整数的字符串,代表水果列表:

map<string, int> fruits{
    {"Apple", 5}, {"Grapefruit", 7}, {"Cherry", 10}, {"Grapes", 16}
};


for (const auto& p : fruits)
    cout << p.first << " " << p.second << endl;
cout << endl << endl;


auto it = fruits.begin();
++++it;

using type = std::pair<class std::basic_string<char, struct std::char_traits<char>, class std::allocator<char> > const, int>;

auto it2 = std::lower_bound(fruits.cbegin(), fruits.cend(), type{"Cherry", 10});
//  auto it3 = std::lower_bound(fruits.cbegin(), fruits.cend(), pair<string, int>{ "Cherry", 10 });
auto it4 = std::lower_bound(fruits.cbegin(), fruits.cend(), pair<const string, int>{ …
Run Code Online (Sandbox Code Playgroud)

c++ stdmap lower-bound upperbound

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

为什么 C++ 标准允许声明指向不存在类型的类成员的指针?

我想知道为什么该语言允许声明指向成员函数/数据的指针,尽管该成员类型不存在,而且我们知道在编译时,必须知道静态类型,并且在使用之前必须知道类型必须是完整类型除了在如此受限制的情况下使用不完整的类型。

这是我的例子:

struct Foo{
    int bar(bool, bool){std::cout << "Foo::bar\n"; return x_;}
    int x_ = 10;
    void do_it()const{cout << "do_it()\n";}
    void do_it(int, bool)const{cout << "do_it(int, bool)\n";};

};


int main(){
    int (Foo::* pMemBar)(bool, bool) = &Foo::bar; // ok
    (Foo{}.*pMemBar)(0, 0); // ok

    int Foo::*pMemX = &Foo::x_;
    std::cout << Foo{}.*pMemX << '\n';


    std::string (Foo::* pMemFn)(char)const; // why this is allowed?
    std::string Foo::* pMemDt = nullptr; // why allowed
}
Run Code Online (Sandbox Code Playgroud)
  • 正如你所看到的一切都OK,直到指针的声明pMemFn,该指针是指向类的成员函数Fooconst与只有一个参数作为char并返回std::string。但是类中没有这样的版本,Foo正如我们所知,编译器确实知道类的所有成员,那么为什么它允许呢?我知道这个指针还没有被取消引用,因此在这样的声明中没有那个类的对象,编译器只有在使用那种类型的对象取消引用它时才会抱怨,class …

c++ member-function-pointers member-data-pointers

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

如何使用“auto”来声明指向重载成员函数的指针?

如果我有一个重载的非静态成员函数,我如何auto为该函数的一个版本声明一个指针?

struct Foo{
   void bar(){}
   void bar(int){}
};

auto ptr = &Foo::bar; // error: unable to deduce 'auto' from '&Foo::bar'
Run Code Online (Sandbox Code Playgroud)

c++ member-function-pointers auto

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

如何在不通过 using 声明公开字符串的情况下显式调用 std::string 析构函数?

我有这个简单的例子:

#include <iostream>
#include <string>

int main(){

   std::string str = "Hi there!";
   std::cout << str << '\n';


   //using std::string;
   str.~string(); // error

}
Run Code Online (Sandbox Code Playgroud)

输出:

g++ main.cxx -std=c++2a -o prog
main.cxx: In function ‘int main()’:
main.cxx:10:15: error: expected class-name before ‘(’ token 10 |    str.~string();
Run Code Online (Sandbox Code Playgroud)
  • 如果我取消注释 main 中包含 using 声明的行,程序可以正常工作,但否则无法编译。

  • 我收到了那个错误,所以我怎么能在std::string不通过 ausing declaration或 a暴露它的情况下调用析构函数using directive?谢谢!

c++ destructor stdstring

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

为什么我们需要 std::partition_point 而可以使用 std::find_if_not 算法?

这是我可能的算法实现std::partition_point

template <typename In_It, typename FUNC>
In_It partitionPoint(In_It b, In_It e, FUNC pred){
    int len = e - b;

    while (len > 0){
        int half = len >> 1;
        In_It middle = b + half;
        if( pred(*middle) ){
            b = middle;
            ++b;
            len = len - half - 1;
        }
        else
            len = half;
    }
      return b;
}
Run Code Online (Sandbox Code Playgroud)

我的代码看起来像 STL,除了使用std::distance, traits... 因此,它检查输入序列并返回一个迭代器,指向谓词成功的序列中的最后一个元素。换句话说,返回的迭代器表示不满足谓词的元素。

int main(){
    std::vector<int> v{1, 3, 5, 7, 9, 1, 3, 6, 8, 10, …
Run Code Online (Sandbox Code Playgroud)

c++ algorithm

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

如何通过复制构造函数复制内置数组?

我们知道内置数组既不能复制也不能赋值。因此,如果它是类/结构/联合的成员数据,则可以让编译器发挥其魔力来复制它们:

struct ArrInt5{
    ArrInt5() = default;
    ArrInt5(ArrInt5 const&) = default; // OK 
    int a[5];
};

ArrInt5 a, b = a; // OK
Run Code Online (Sandbox Code Playgroud)
  • 有时情况并非如此,例如,如果数组包含非默认可构造对象的对象。在这种情况下,我们确实需要定义复制因子来完成这项工作:

      struct Bar{
          // deleted default ctor
          Bar(int x) : x_(x){}
          int x_ = 0;
      };
    
      struct Foo{
          Foo();
          Foo(Foo const&);
    
          Bar arr_[5];
      };
    
      Foo::Foo() : arr_{0, 1, 2, 3, 4}
      {}
    
      Foo::Foo(Foo const& rhs) : arr_{rhs.arr_[0], rhs.arr_[1], rhs.arr_[2], rhs.arr_[3], rhs.arr_[4]}
      {}
    
    Run Code Online (Sandbox Code Playgroud)
  • 正如您所看到的,Foo有一个由五个类型的对象组成的内置数组,struct Bar该类型不可默认构造,因此默认构造函数和复制构造函数必须对其进行初始化(arr_)。

  • 问题是:如果数组很大(比如 100 万个元素),如何初始化该数组?我应该逐个元素地硬复制它们吗?或者有一些解决方法?

    • 我知道很多人会推荐我使用等效的 STL 容器,std::array但我不讨论这个主题,我想问是否有针对我的内置非默认可构造对象数组的解决方法。

c++ arrays copy-constructor

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