小编son*_*yao的帖子

是否可以在没有typedef的情况下声明转换函数返回数组引用?

这是一个返回数组引用的转换函数:

struct S { 
    typedef int int_array_20[20];
    operator int_array_20& ();
};
Run Code Online (Sandbox Code Playgroud)

没有可能做同样的事情typedef吗?我尝试过的:

struct S { 
    operator int (&()) [10];
};
Run Code Online (Sandbox Code Playgroud)

但克朗抱怨道:

error: C++ requires a type specifier for all declarations
    operator int (&()) [10];
                  ~ ^
error: conversion function cannot have any parameters
    operator int (&()) [10];
    ^
error: must use a typedef to declare a conversion to 'int [10]'
error: conversion function cannot convert to an array type
Run Code Online (Sandbox Code Playgroud)

请问:

必须使用typedef来声明转换为'int [10]'

意味着typedef不可或缺?

编辑
如果typedef …

c++ typedef type-conversion conversion-operator language-lawyer

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

当auto遇到多态和虚函数时,什么是正确的行为?

class B {
    public:
    virtual void f(){
        printf("B\n");
    }
};
class D : public B { 
    public:
    void f() {
        printf("D\n");
    }
};

int main(void)  
{  
    B* d = new D();
    d->f();
    auto b = *d; 
    b.f();
}
Run Code Online (Sandbox Code Playgroud)

因为d->f();,输出是D.这是正确的.但是b.f();,输出是B.这是正确的吗?

c++ auto c++11

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

const传播到std ::指针数组

为什么std::array在这里以不同方式实例化数据类型

using T = const int *;
std::array<T, 4> x = { &a, &b, &c, &d }; // name: class std::array<int const *,4>
x[0] = &c; // OK    : non-constant pointer
*x[0] = c; // Error : constant data
Run Code Online (Sandbox Code Playgroud)

相比这里?

using T = int *;
std::array<const T, 4> x = { &a, &b, &c, &d }; // name: class std::array<int * const,4>
x[0] = &c; // Error : constant pointer
*x[0] = c; // OK    : non-constant data …
Run Code Online (Sandbox Code Playgroud)

c++ arrays pointers const type-deduction

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

从函数返回的对象的延长生命周期

关于从函数返回并绑定到rvalue/const左值引用的对象的生命周期的延长,我有一些不清楚的信息.来自这里的信息.

不会扩展对return语句中函数的返回值的临时绑定:它会在返回表达式的末尾立即销毁.这样的函数总是返回一个悬空引用.

如果我理解正确,引用声称返回语句返回的对象的生命周期是不可扩展的.但最后一句话表明,它只适用于返回引用的函数.
在海湾合作委员会,从下面的代码我得到以下输出:

struct Test
{
  Test() { std::cout << "creation\n"; }
  ~Test() { std::cout << "destruction\n"; }
};

Test f()
{
    return Test{};   
}

int main()
{
    std::cout << "before f call\n";
    Test && t = f();
    std::cout << "after f call\n";
}
Run Code Online (Sandbox Code Playgroud)
before f call
creation
after f call
destruction
Run Code Online (Sandbox Code Playgroud)

所以看起来生命延长了.
是否应延长与此类参考相关的临时对象的生命周期?您还可以提供更明确的信息来源吗?

c++ reference temporary lifetime language-lawyer

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

模板和重载

  template<class Key1, class Key2, class Type> class DualMultimapCache
  {
  public:
     std::list<std::reference_wrapper<Type>> get(Key1 const & key);
     std::list<std::reference_wrapper<Type>> get(Key2 const & key);
     template<class ...Args> Type & put(Key1 const & key, Args const & ...args);
     template<class ...Args> Type & put(Key2 const & key, Args const & ...args);
  };
Run Code Online (Sandbox Code Playgroud)

在这里,我有一个类的公共接口.基础数据结构无关紧要.一切都将只是正常工作时Key1,并Key2有不同的类型.如果它们最终成为相同的类型,则过载可能是不可能的.我这是对的吗?

如果我是,有没有办法分离过载,同时保持签名尽可能干净?

编辑:这是一个更深入的样本

  template<class Key1, class Key2, class Type> class DualMultimapCache
  {
  public:
     std::list<std::reference_wrapper<Type>> get(Key1 const & key);
     std::list<std::reference_wrapper<Type>> get(Key2 const & key);
     template<class ...Args> Type & put(Key1 const & key, …
Run Code Online (Sandbox Code Playgroud)

c++ templates overloading overload-resolution class-template

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

基于范围的for循环在临时范围上

感谢valgrind中的一些分段错误和警告,我发现这段代码不正确,并且在for-range循环中有一些悬空引用.

#include<numeric>
#include<vector>

auto f(){
    std::vector<std::vector<double>> v(10, std::vector<double>(3));
    iota(v[5].begin(), v[5].end(), 0);
    return v;
}

int main(){
    for(auto e : f()[5])
        std::cout << e << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

它看起来好像beginend从临时取出,并循环丢失.

当然,一种方法是做

    auto r = f()[5];
    for(auto e : r)
        std::cout << e << std::endl;
Run Code Online (Sandbox Code Playgroud)

但是,我想知道为什么for(auto e : f()[5])是一个错误,如果有更好的方法或某种方式设计f或甚至容器(std::vector)以避免这个陷阱.

随着迭代循环是比较明显的,为什么这个问题发生(beginend来自不同的临时对象)

for(auto it = f()[5].begin(); it != f()[5].end(); ++it)
Run Code Online (Sandbox Code Playgroud)

但是在for-range循环中,就像在第一个例子中一样,这个错误似乎很容易.

c++ temporary-objects c++11 c++20 for-range

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

从右值引用到base的构造函数 - 可行(gcc)或不(clang) - 谁是对的

最近有一个恭维问题,由此片段说明:

struct Base
{
};

template<typename T>
struct A : Base
{
    A(){}
    A(Base&&) {}
};

A<int> foo()
{
    A<double> v;
    return v;
}


int main()
{
    auto d = foo();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Gcc说没关系,但是clang不同意并说"候选构造函数不可行:第一个参数A(Base &&){}"没有已知的从'A'到'Base &&'的转换,请亲自看看:https://godbolt.org/Z/Y7mwnU

任何一种读者是否能够帮助支持任何一种观点?

c++ gcc return clang language-lawyer

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

C++ 中的 constexpr int 和 constexpr double

我遇到了一个奇怪的案例。

// this does not work, and reports:
// constexpr variable 'b' must be initialized by a constant expression
int main() {
  const double a = 1.0;
  constexpr double b = a;
  std::cout << b << std::endl;
}

// this works...
int main() {
  const int a = 1;
  constexpr int b = a;
  std::cout << b << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

有什么特别之处double所以它不能constexpr工作?

c++ double integer constexpr c++11

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

std::map, std::unordered_map - 初始化列表中的缩小转换

它是错误还是标准允许?

#include <iostream>
#include <map>
#include <unordered_map>

int main() {
    std::unordered_map<int,int> mm {{44,44}, {33.3, 54}, {222.2,222.2}};
    for(auto& [f,s] :mm) {
        std::cout<<f<<" - "<<s<<std::endl;
    }

    std::map<int,int> m {{44,44}, {33.3, 54}, {222.2,222.2}};
    for(auto& [f,s] :m) {
       std::cout<<f<<" - "<<s<<std::endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

wandbox.org 上使用 clang10 和 gcc10对其进行测试。std::set和没有这样的问题std::unordered_set

c++ stdmap c++17

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

调用具有不同右值引用类型的重载函数时出现意外输出

当使用不同的右值引用类型调用重载函数时,我在代码中遇到了意外行为。下面的代码片段演示了这个问题:

#include <iostream>

void foo(int&& x)
{
    std::cout << "int Rvalue: " << x << std::endl;
}

void foo(float&& x)
{
    std::cout << "float Rvalue: " << x << std::endl;
}

int main()
{
    int int_x = 1;
    float float_x = 5.14f;

    foo(int_x);
    foo(float_x);
}
Run Code Online (Sandbox Code Playgroud)

输出

float Rvalue: 1
int Rvalue: 5
Run Code Online (Sandbox Code Playgroud)

我没有得到预期的输出(应该是“int Rvalue:1”和“float Rvalue:5”),而是观察到相反的顺序。我发现这种行为令人困惑,并且希望了解为什么会发生这种情况。

我确保理解右值引用的概念以及基于它们的重载如何工作。我也尝试过搜索类似的问题,但没有找到任何直接解决此特定情况的问题。

任何指导或解释将不胜感激。预先感谢您的帮助!

c++ overloading rvalue-reference lvalue-to-rvalue c++11

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