小编use*_*538的帖子

当类和函数具有相同名称时会发生什么?

#include <iostream>
using namespace std;

struct test
{
    test(){cout<<"class"<<endl;}
};
void test(){cout<<"function"<<endl;}

int main()
{
    test();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

function  
Run Code Online (Sandbox Code Playgroud)

(VS2013 ang gcc 4.8.1)

为什么选择功能?是不是模棱两可?

c++ ambiguity ambiguous-call

18
推荐指数
2
解决办法
1336
查看次数

枚举的声明点

枚举类型的声明有什么意义?它是在枚举名称后面吗?我看过Standard C++ 14(n4296)§3.3.2/ 3:

枚举的声明点紧跟在enum-specifier(7.2)或其第一个opaque-enum-declaration(7.2)中的标识符(如果有)之后,以先到者为准

但是当我试图重现它时;

template <class T>
struct CL
{
    using UndType = int;
};

enum class E: CL<E>::UndType;  //error: E is undefined
Run Code Online (Sandbox Code Playgroud)

我在所有编译器上都有一个错误,虽然枚举的枚举E位置在标识符之后并且必须是可见的.

c++ enums declaration c++11 c++14

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

转换运算符的模板参数类型推导

我看到C++ 11标准中的例子(n3337,14.8.2.3/7)

struct A {
template <class T> operator T***();
};
A a;
const int * const * const * p1 = a; // T is deduced as int, not const int
Run Code Online (Sandbox Code Playgroud)

并尝试由不同的编译器重现它.我通过在转换函数中添加类型为T的声明来稍微改变了示例

struct A {
    template <class T> operator T***()
    {
        T t;  //if T==const int, then it is error (uninitialized const)
        return nullptr;
    }
};
A a;
const int * const * const * p1 = a;

int main(){}
Run Code Online (Sandbox Code Playgroud)

所有编译器(VS2014,gcc 5.1.0和clang 3.5.1)都在"t"的声明中给出了一个错误,这意味着T被推导为const int.这是为什么?这是一些扩展吗?

c++ templates operator-overloading c++11 type-deduction

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

typedef和具有相同名称的模板参数

为什么这种情况不正确(这是合乎逻辑的)

template <typename T>
struct Der: public Base
{
    typedef int T;
    T val;
};
Run Code Online (Sandbox Code Playgroud)

,但那个案子是对的吗?

struct Base
{
    typedef int T;
};

template <typename T>
struct Der: public Base
{
    T val;
};
Run Code Online (Sandbox Code Playgroud)

标准14.6.1/7说:

在类模板的定义中或在模板定义之外出现的这种模板的成员定义中,对于不依赖于模板参数的每个基类(14.6.2),如果名称是基类或基类成员的名称与template-parameter的名称相同,基类名称或成员名称隐藏模板参数名称(3.3.7).

为什么这里不含糊?

c++ templates typedef ambiguous language-lawyer

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

指向不完整类型的成员函数的指针

我不明白为什么为类添加前向声明会将其指针的大小更改为成员类型

#include <iostream>
using namespace std;

int main()
{
    //struct CL;
    //cout<<sizeof(int (CL::*)())<<endl; 
    struct CL{};
    cout<<sizeof(int (CL::*)())<<endl;
}
Run Code Online (Sandbox Code Playgroud)

输出VS2013:
4

但是如果我取消注释main()中的前两行,那么输出是不同的:
16
16

因此,在struct CL的定义之前只添加一个前向声明只会增加指向CL成员的指针的大小.为什么?我知道成员函数指针的大小取决于类型的结构(例如,虚函数和基类可能会增加它),但为什么sizeof运算符可以应用于指向不完整类型成员的指针?还是不行?我没有在标准中找到它

c++ pointer-to-member incomplete-type

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

std::variant 和不明确的初始化

考虑以下代码:

void fnc(int)
{
    std::cout << "int";
}

void fnc(long double)
{
    std::cout << "long double";
}

int main()
{
    fnc(42.3); // error
}
Run Code Online (Sandbox Code Playgroud)

由于对 的调用不明确,它会给出错误fnc
但是,如果我们编写下面的代码:

std::variant<int, long double> v{42.3};
std::cout << v.index();
Run Code Online (Sandbox Code Playgroud)

输出为1,这表明已选择double->转换。long double据我所知,std::variant遵循有关转换等级的 C++ 规则,但这个示例显示了差异。这种行为有什么解释吗?

c++ std language-lawyer c++17

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

C++:在自己内部摧毁lambda

#include <iostream>
#include <functional>

int global = 9;
std::function<void()> functor;

int main()
{
    int* ptr = &global;
    functor = [ptr]
    {
        functor = nullptr;
        std::cout << *ptr << std::endl;
    };

    functor();
}
Run Code Online (Sandbox Code Playgroud)

这是ptr由lambda捕获的变量,并且在functor()调用functor中首先删除functor = nullptr然后访问ptr.我认为它ptr已被破坏,因为它是一个删除的仿函数的字段.所有编译器成功执行该程序而没有崩溃并打印"9",但我仍然怀疑这不是未定义的行为.有人可以证实吗?

c++ lambda c++11

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

结构化绑定中的变量类型

#include <type_traits>

int main()
{
    int arr[1] = { 6 };

    auto& ref1 = arr[0];  
    static_assert( std::is_same_v<decltype( ref1 ), int&> ); //ok

    auto& [ ref2 ] = arr;
    static_assert( std::is_same_v<decltype( ref2 ), int> ); //ok
    static_assert( std::is_same_v<decltype( ref2 ), int&> ); //error
}
Run Code Online (Sandbox Code Playgroud)

标识符ref1ref2该示例之间的重要区别是什么?据我所知,ref2在结构绑定中也有一个引用类型,但为什么要为它decltype指示一个非引用类型?

c++ decltype auto type-deduction c++17

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

通过模糊转换运算符引用绑定

#include <iostream>
using namespace std;

struct CL2
{
    CL2(){}
    CL2(const CL2&){}
};

CL2 cl2;

struct CL1
{
    CL1(){}
    operator CL2&(){cout<<"operator CL2&"; return cl2;}
    operator const CL2&(){cout<<"operator const CL2&"; return cl2;}
};

CL1 cl1;

int main()
{
    CL1 cl1;
    CL2 cl2 (cl1);
}
Run Code Online (Sandbox Code Playgroud)

clang和gcc都提供了不明确的转换运算符,但Visual Studio编译好并打印"operator const CL2&".按标准怎么做才对?
正如我所说,将CL1转换为const CL2&是在复制初始化上下文中(作为cl2对象的直接初始化的一部分).我看过n4296草案,[over.match.copy]:

假设"cv1 T"是要初始化的对象的类型,使用T类类型,候选函数选择如下:
- T的转换构造函数(12.3.1)是候选函数.
- 当初始化表达式的类型是类类型"cv S"时,将考虑S及其基类的非显式转换函数.初始化临时绑定到构造函数的第一个参数时,其中参数的类型为"引用可能的cv-qualified T",并且在直接初始化类型的对象的上下文中使用单个参数调用构造函数"cv2 T",也考虑了显式转换函数.那些未隐藏在S中并且产生其cv非限定版本与T的类型相同或者是其派生类的类型的候选函数.返回"引用X"的转换函数返回lvalues或xvalues,具体取决于类型X的引用类型,因此被认为是为此选择候选函数的过程产生X.

即两个转换运算符被认为是返回CL2和const CL2(不仅仅是没有const的CL2)并且它仍然需要解决,哪个转换更好:CL2 - > const CL2&或const CL2 - > const CL2&.第二种情况似乎更合适.在这种情况下是否应考虑更好的资格转换?或两种情况都是身份转换?我在标准版中找不到它

c++ visual-studio copy-initialization c++11 c++14

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

将静态全局变量声明为内联有任何意义吗?

考虑一下,在头文件中声明了全局变量(不是静态类成员!):

inline static int i{};
Run Code Online (Sandbox Code Playgroud)

对于我测试过的几个编译器来说,它是有效的构造,并且实验证明,尽管也将其声明为内联的,但它们将在不同的转换单元中创建多个不同的对象(这意味着该变量中仅一个实例必须存在于程序中)。那么,static关键字比inline在这种情况下具有更高的优先级吗?

c++ static global inline c++17

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