小编Des*_*tor的帖子

复制构造函数中省略号的含义是什么?

考虑以下程序:

#include <iostream>
struct Test
{
    int a;
    Test() : a(3)
    { }
    Test(const Test& t...)
    {
        std::cout<<"Copy constructor called\n";
        a=t.a;
    }
    int get_a()
    {
        return a;
    }
    ~Test()
    {
        std::cout<<"Destructor is called\n";
    }
};
int main()
{
    Test t;
    Test* t1=new Test(t);
    std::cout<<t.get_a()<<'\n';
    std::cout<<t1->get_a()<<'\n';
    delete t1;
}
Run Code Online (Sandbox Code Playgroud)

仔细观察复制构造函数参数中的三个点我尝试这个程序时真的很惊讶.有什么用?这是什么意思?

语言规范对此有何看法?

我知道三个点用于表示变量函数(如等)中的变长参数printf()以及scanf()C99引入的可变参数宏.在C++中,如果我没有错,它们将用于可变参数模板.
这段代码是否形成良好?这个可变参数构造函数是否可以使用任意数量的参数?

它在g ++ 4.8.1和MSVS 2010上编译并运行良好.

c++ variadic-functions copy-constructor

15
推荐指数
2
解决办法
694
查看次数

为什么operator void*()转换函数被添加到C++流类中?

operator void*() constC++流类中有一个转换函数.这样所有流对象都可以隐式转换为void*.在与SO的程序员交互过程中,他们建议我不要使用,void*除非你有充分的理由使用它.void*是一种删除类型安全和错误检查的技术.因此,由于该转换功能的存在,以下程序完全有效.这是C++标准库中的一个缺陷.

#include <iostream>
int main()
{
       delete std::cout;
       delete std::cin;
}
Run Code Online (Sandbox Code Playgroud)

在这里查看现场演示.

上述程序在C++ 03中有效,但在C++ 11及更高版本的编译器中编译失败,因为此转换函数已被删除.但问题是,如果它是危险的,它是C++标准库的一部分?允许将流对象转换为的目的是void*什么?有什么用?

c++ void-pointers c++-standard-library delete-operator c++11

13
推荐指数
2
解决办法
1902
查看次数

隐藏成员模板的模板参数

来自temp.local:

在出现在类模板定义之外的类模板成员的定义中,类模板成员的名称隐藏任何封闭类模板的模板参数的名称(但不是模板参数的名称)成员,如果成员是类或函数模板).[例如:

template<class T> struct A {
  struct B { /* ... */ };
  typedef void C;
  void f();
  template<class U> void g(U);
};

template<class B> void A<B>::f() {
  B b;              // A's B, not the template parameter
}

template<class B> template<class C> void A<B>::g(C) {
  B b;              // A's B, not the template parameter
  C c;              // the template parameter C, not A's C
}
Run Code Online (Sandbox Code Playgroud)

- 结束例子]

问题是,我尝试过的每个编译器(g ++,vc,icc,clang)都将C A<B>::g(C)作为A的成员名称处理,并且不编译该示例.

这是一个常见的错误吗?

c++ standards templates name-lookup

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

模板函数调用歧义错误

我不熟悉模板.我刚开始学习它.为什么我在以下程序中遇到错误?

#include <iostream>
#include <string>
using std::cout;
using std::string;
template<class C>
C min(C a,C b) {
    return a<b?a:b;
}
int main()
{
    string a="first string";
    string b="second string";
    cout<<"minimum string is: "<<min(a,b)<<'\n';
    int c=3,d=5;
    cout<<"minimum number is: "<<min(c,d)<<'\n';
    double e{3.3},f{6.6};
    cout<<"minimum number is: "<<min(e,f)<<'\n';
    char g{'a'},h{'b'};
    cout<<"minimum number is: "<<min(g,h)<<'\n';
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

错误:

13  [Error] call of overloaded 'min(std::string&, std::string&)' is ambiguous

6   [Note] C min(C, C) [with C = std::basic_string<char>]
Run Code Online (Sandbox Code Playgroud)

请帮我.

c++ templates ambiguity ambiguous ambiguous-call

11
推荐指数
2
解决办法
799
查看次数

什么是VC++中的光纤安全优化?

我正在阅读有关MSDN上的光纤安全优化的文章.它说

使用__declspec(thread)声明的数据通过线程局部存储(TLS)数组引用 .TLS数组是系统为每个线程维护的地址数组.此数组中的每个地址都给出了线程本地存储数据的位置.光纤是一个轻量级对象,由堆栈和寄存器上下文组成,可以在各种线程上进行调度.光纤可以在任何线程上运行.由于光纤可能会在以后的另一个线程上被换出并重新启动,因此不能将TLS数组的地址作为函数调用中的公共子表达式进行缓存或优化

什么是光纤安全优化?使用它的实际目的是什么?他们为什么这么说"因为光纤可能会被换出并稍后在另一个线程上重新启动,所以不能将TLS数组的地址缓存或优化为函数调用中的公共子表达式."?为什么以及何时应该预防?

c++ arrays optimization multithreading visual-c++

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

是否保证默认构造函数自动将内置类型初始化为0?

在你开始将其标记为重复之前,我已经读过这个 .但它没有回答我的问题.链接的问题谈到了C++ 98和C++ 03,但我的问题是关于C++ 11引入的默认构造函数.

考虑以下程序(请参阅此处的实时演示):

#include <iostream>
struct Test
{
    int s;
    float m;
    Test(int a,float b) : s(a),m(b)
    { }
    Test()=default;
}t;
int main()
{
    std::cout<<t.s<<'\n';
    std::cout<<t.m<<'\n';
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,编译器提供的默认构造函数总是初始化内置类型,在C++ 11和C++ 14中默认为0,当它们是class&struct成员时.这种行为是否由C++ 11标准保证?

c++ initialization default-constructor language-lawyer c++11

11
推荐指数
3
解决办法
1058
查看次数

为什么const变量不需要在C中初始化?

const必须初始化C++中的变量意味着uninitialized const variable不可能并且它是编译器错误.但为什么C语言也不一样呢?考虑以下编译精细C的程序:

#include <stdio.h>
int main()
{
    const int a;
}
Run Code Online (Sandbox Code Playgroud)

允许的原因是uninitialized const什么?如果C也遵循与C++相同的规则,那会不会很好?是否由于性能问题,每次调用函数并初始化需要时间时,需要初始化本地const变量?

c initialization const

10
推荐指数
2
解决办法
2448
查看次数

转换操作符函数在g ++中编译得很好,但在其他编译器中却没有.为什么?

考虑以下计划:

struct S {
    using T = float;
    operator T() { return 9.9f; }
};
int main() {
    S m;
    S::T t = m;
    t = m.operator T(); // Is this correct ?
}
Run Code Online (Sandbox Code Playgroud)

该程序在g ++中编译良好(请参阅此处的实时演示)

但它在clang ++,MSVC++和Intel C++编译器的编译中失败了

clang ++给出以下错误(请参阅此处的在线演示)

main.cpp:8:20: error: unknown type name 'T'; did you mean 'S::T'?
    t = m.operator T(); // Is this correct ?
                   ^
                   S::T
main.cpp:2:11: note: 'S::T' declared here
    using T = float;
Run Code Online (Sandbox Code Playgroud)

MSVC++给出以下错误(请参阅此处的实时演示)

source_file.cpp(8): error …
Run Code Online (Sandbox Code Playgroud)

c++ g++ visual-c++ language-lawyer clang++

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

为什么gcc -Wformat没有在unsigned int上警告printf%d?

以下程序具有未定义的行为:

#include <stdio.h>

int main(void)
{
    unsigned int x = -100; // This is fine, becomes UINT_MAX - 100
    printf("%d\n", x); // This is undefined behavior.
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

C99 7.19.6.1p8状态%d需要一个int参数.

C99 7.19.6.1p9声明"如果任何参数不是相应转换规范的正确类型,则行为 未定义."

但是,gcc -Wformat(包含在内-Wall)不会抱怨上述程序,为什么?这是一个错误,还是故意遗漏?

从gcc手册页:

-Wformat
Run Code Online (Sandbox Code Playgroud)

检查电话"printf""scanf"等,以确保提供参数指定适当的格式字符串类型,并在格式字符串指定的转换意义

c gcc gcc-warning format-specifiers format-string

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

为什么从C++中删除了重载关键字?

我正在读这个.@NPE给出的答案讲述了有趣的历史事实并说,

  • 在早期的C++中,曾经有一个特殊的关键字(重载)必须用于将标识符声明为重载;

那么,删除重载关键字的原因是什么?我没有Design and Evolution of C++Stroustrup.有关重载关键字有什么问题?

c++ overloading

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