小编Mae*_*tro的帖子

为什么模板函数中的 strcmp() 返回不同的值?

我正在再次阅读“C++ Primer,第 5 版”。在关于模板的第16章中,有一个“模板非类型参数”的例子:

template<unsigned N, unsigned M>
int compare(const char (&p1)[N], const char (&p2)[M])
{
    return strcmp(p1, p2);
}

int main()
{

    cout << compare("hi", "mom") << endl;
    cout << strcmp("hi", "mom") << endl;


    std::cout << "\ndone!\n";
}
Run Code Online (Sandbox Code Playgroud)
  • 众所周知,strcmp()比较两个字符串并返回0相等,如果str1大于则为str2正值,如果str1小于则为负值str2,这就是我在main()调用strcmp().

  • 问题出在调用strcmp()模板函数内部的书中示例中,所以当我运行程序时,我得到:

输出:

-5
-1
Run Code Online (Sandbox Code Playgroud)

代码中有什么问题?为什么两者对相同的参数给出不同的值?

c++ templates strcmp non-type

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

如果我的类是文字类,那么将我的类的对象声明为constexpr是否多余?

我有一个constexpr类Debug:

struct Debug {
  constexpr Debug(bool a, bool b, bool c) : a(a), b(b), c(c) {}
  bool a, b, c;
  constexpr bool get() const { return a; }
};

int main() {
  Debug dbg(true, false, false); // is dbg constexpr object?
  constexpr Debug dbg2(0, 0, 0); // is constexpr redundant here?
}
Run Code Online (Sandbox Code Playgroud)

如您所见,这dbg是一个constexpr对象,因为它是用constexpr构造函数初始化的,所以如果我用constexpr对其进行限定,那有什么意义呢?

  • 我不知道之间的区别dbgdbg2。谢谢。

c++ oop constexpr

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

是否可以将引用类型别名与指针运算符一起使用来声明对指针的引用?

我在这里有一个简单的示例:我使用类型别名using using关键字作为引用类型,然后我想知道是否可以通过指针运算符(*)使用该类型别名来声明对指针的引用:

int main(){

    using ref_int = int&;

    int x = 10;
    int* p = &x;

    //int*(&rpx) = p;
    //ref_int * rptrx = p; // pointer to reference is not allowed.
    *ref_int(rptrx) = p; // rptrx is undefined

}
Run Code Online (Sandbox Code Playgroud)
  • 因为出于好奇,当我使用Element的类型时,std::vector<int>::reference我想将其与指针运算符结合*以声明对指针的引用:

    int* ptr = new int(1000);
    std::vector<int>::*(reference rptr) = ptr; // error: expected expression
    
    Run Code Online (Sandbox Code Playgroud)
  • 但是我可以结合使用指针类型别名和引用运算符“&”来声明它:

    using pInt = int*;
    
    int i = 57;
    int* ptrI = &i;
    pInt(&rpInt) = ptrI;
    
    cout << *rpInt << endl;
    
    Run Code Online (Sandbox Code Playgroud)

**我知道我没有指向引用的指针,因为引用只是已有对象的别名,而指针是一个对象,因此我们可以有一个指向它的指针或引用。

c++ pointers reference type-alias

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

为什么只有当我的容器有超过 32 个元素时 std::sort 才调用交换?

你好,我有一个简单的问题:

class A 
{
public:
    A(int);
    A(const A&);
    A& operator=(const A&);
    ~A();
private:
    int* ptr_;

    friend bool operator<(const A&, const A&);
    friend void swap(A&, A&);
};

A::A(int x) : 
    ptr_(new int(x))
{}

A::A(const A& rhs) :
    ptr_(rhs.ptr_ ? new int(*rhs.ptr_) : nullptr)
{}

A& A::operator = (const A & rhs)
{
    int* tmp = rhs.ptr_ ? new int(*rhs.ptr_) : nullptr;
    delete ptr_;
    ptr_ = tmp;

    return *this;
}

A::~A()
{
    delete ptr_;
}

bool operator<(const A& lhs, const A& rhs) …
Run Code Online (Sandbox Code Playgroud)

c++ swap std

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

流如何与另一个冲洗连接?

我正在阅读C ++ Primer,第5版。当谈论冲洗流时,它说:

输出流可能会绑定到另一个流。在这种情况下,每当读取或写入绑定流时,都会刷新绑定流的缓冲区。默认情况下,cin和cerr都与cout绑定在一起。因此,读取cin或写入cerr会冲洗cout中的缓冲区。

我试图通过一个例子来理解这一点:

int main() {

    std::ofstream out("data.txt");
    std::ifstream in("data.txt");

    //in.tie(&out);// commenting this will print nothing

    out << "Hello there!";
    std::string str;
    while (in >> str)
        std::cout << str << " ";

    out.close();
    in.close();
}
Run Code Online (Sandbox Code Playgroud)

如您在上方看到的输入和输出文件流对象inout使用相同的文件,因此输出一个打开文件“ data.txt”并向其中写入一些行,但不保存它,输入流尝试读取内容未保存文件的内容。

  • 如果将输入流对象绑定到该对象inout则可以正确获取内容。这是否意味着in军队out被刷新?

  • 如果我注释掉该行,in.tie(&out)那么我不会使用in来获取内容?

请在这里向我解释它是如何工作的。先感谢您。

c++ flush stream

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

如何调用由ctor提供的带有所有默认参数的类的默认构造函数?

据说在C ++入门5th版中,为所有参数提供默认参数的构造函数也定义了默认构造函数:

class Point {
    public:
        //Point(); // no need to define it here.
        Point(int x = 0, int y = 0) : x_(x), y_(y){
            std::cout << "Point(int=0, int=0)" << std::endl;
        } // synthesize default constructor Point()
        int x_;
        int y_;
};

int main(){
    Point pt; // default ctor Point() or Point(int, int)?
    Point pt2 = Point(); // this won't compile?!
}
Run Code Online (Sandbox Code Playgroud)

正如你可以看到上面我想出于某种原因调用默认的构造函数Point()不是Point(int, int),但我得到了后者不是默认的构造函数?

那么是否可以调用由为所有参数提供默认参数的构造函数提供的类的默认构造函数?谢谢。

c++ default-constructor

7
推荐指数
2
解决办法
90
查看次数

模板显式实例化如何工作以及何时工作?

这是 C++ 入门第 5 版的练习:

“练习 16.26:假设NoDefault是一个没有默认构造函数的类,我们可以显式实例化vector<NoDefault>吗?如果没有,为什么不呢?”

这是我的猜测:

是的,我们可以实例化它:

template <typename T>
class Foo
{
public:
    void func(){cout << x_.value_ << endl;}
private:
    T x_;
};

class Bar
{
public:
    Bar(int x) : value_(x){}
    void print(){}
private:
    int value_{};
template <class T>
friend class Foo;
};

extern template class Foo<Bar>; // instantiation declaration
template class  Foo<Bar>; // instantiation definition


int main()
{

  //  Foo<Bar> f;
}
Run Code Online (Sandbox Code Playgroud)

代码工作正常,但如果我取消注释 main 中的行,我会按预期出现错误,因为Bar它不是默认构造的。

如果我使用相同的类Bar作为元素类型,std::vector它不起作用: …

c++ template-instantiation

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

为什么我的 forward_ 函数不适用于右值?

我已经了解如何std::move工作并实现我自己的版本仅供练习。现在我试图了解如何std::forward工作:

到目前为止,我已经实现了这一点:

#include <iostream>


template <typename T>
T&& forward_(T&& x)
{
    return static_cast<T&&>(x);
}


/*template <typename T>
T&& forward_(T& x)
{
    return static_cast<T&&>(x);
}*/

void incr(int& i)
{
    ++i;
}

void incr2(int x)
{
    ++x;
}

void incr3(int&& x)
{
    ++x;
}

template <typename T, typename F>
void call(T&& a, F func)
{
    func(forward_<T>(a));
}


int main()
{

    int i = 10;
    std::cout << i << '\n';
    call(i, incr);
    std::cout << i << '\n';

    call(i, incr2); …
Run Code Online (Sandbox Code Playgroud)

c++ perfect-forwarding

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

非抛出函数指针可以指向抛出函数吗?

在关于异常规范的 C++ Primer 上noexcept,据说指向可能抛出隐式(没有异常规范定义,例如:)void(*p)();或显式(void(*p)() noexcept(false);)的函数的指针可以指向任何函数,甚至指向不抛出的函数。

另一方面,一个不能抛出异常的函数指针(noexcept例如void(*p) noexcept;)只能指向一个不会抛出异常的函数。

我发现这非常合乎逻辑,因为第一个指针可以从抛出函数指针指向非抛出函数,而第二个指针也很合乎逻辑。

我尝试过这个来了解更多:

void func1(){ // may throw
    std::cout << "func1()\n";
}

void func2() noexcept(false){ // may throw
    std::cout << "func2()\n";
}

void func3() noexcept(true){ // won't throw
    std::cout << "func3()\n";
}

void func4() noexcept{ // won't throw
    std::cout << "func4()\n";
}


int main(int argc, char* argv[]){

    void(*pFn1)();
    pFn1 = func1; // OK
    pFn1 = func2; // OK
    pFn1 = func3; // OK
    pFn1 …
Run Code Online (Sandbox Code Playgroud)

c++ function-pointers noexcept

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

C++ 入门第 5 版。函数模板重载

C++ Primer一书中,有一个关于函数模板重载的例子:

// print any type we don't otherwise handle
template <typename T> string debug_rep(const T &t)
{
    cout << "debug_rep(T const&)\n";
    ostringstream ret; // see § 8.3 (p. 321)
    ret << t; // uses T's output operator to print a representation of t
    return ret.str(); // return a copy of the string to which ret is bound
}

// print pointers as their pointer value, followed by the object to which the pointer points
// NB: this …
Run Code Online (Sandbox Code Playgroud)

c++ template-argument-deduction function-templates-overloading

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