小编Kar*_*iak的帖子

静态constexpr成员的统一初始化

根据: constexpr静态数据成员给出未定义的引用错误 静态constexpr类成员必须满足两个要求:

template <typename Tp>
struct wrapper {
  static constexpr Tp value{}; // 1
};

template<typename Tp>
constexpr Tp wrapper<Tp>::value; // 2 

struct foo {
};

int main() {
  auto const& x = wrapper<foo>::value;
  (void)x;    
}
Run Code Online (Sandbox Code Playgroud)
  1. 在类定义中初始化(因为它是constexpr)
  2. 在类定义之外定义(因为它是静态的)

如果我改变1.统一初始化

template <typename Tp>
struct wrapper {
  static constexpr auto value = Tp{}; // uniform initialization
};

template<typename Tp>
constexpr Tp wrapper<Tp>::value;
Run Code Online (Sandbox Code Playgroud)

编译器抱怨冲突的声明:

$ g++ prog.cc -Wall -Wextra -std=c++1z -pedantic
prog.cc:7:31: error: conflicting declaration 'constexpr const Tp wrapper<Tp>::value' constexpr Tp wrapper<Tp>::value; …
Run Code Online (Sandbox Code Playgroud)

c++ static-members uniform-initialization constexpr c++11

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

我可以对引用元组的向量进行排序吗?

下面的代码:

std::vector<std::tuple<int&>> v;
int a = 5; v.emplace_back(a);
int b = 4; v.emplace_back(b);
int c = 3; v.emplace_back(c);
int d = 2; v.emplace_back(d);
int e = 1; v.emplace_back(e);
std::sort(std::begin(v), std::end(v));
Run Code Online (Sandbox Code Playgroud)

用gcc/libstdc ++编译vs clang/libc ++ binary给出了不同的结果.

对于gcc/libstdc ++,将一个元素复制到所有其他引用.

5 4 3 2 1 
5 5 5 5 5
Run Code Online (Sandbox Code Playgroud)

首先,我认为clang/libc ++的行为符合预期,但它最多只能处理一个向量中的5个元素(因为小容器有一个特例).

5 4 3 2 1 
1 2 3 4 5 
Run Code Online (Sandbox Code Playgroud)

传递更多元素时,结果类似于gcc.

5 4 3 2 1 0 
3 4 5 5 5 5
Run Code Online (Sandbox Code Playgroud)

因此,std::sort …

sorting tuples c++11

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

返回统一初始化参考有效吗?

此代码示例是否有效?

using ref = char&;

ref foo(ref x) {
  return ref{x};
}

int main() {
  char a;
  foo(a);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

似乎:

  • clang 3.5说YES
  • gcc 4.9说没有

    main.cpp: In function 'char& foo(ref)':
    main.cpp:4:15: error: invalid cast of an rvalue expression of type 'char' to type 'ref {aka char&}'
       return ref{x};
                   ^
    
    Run Code Online (Sandbox Code Playgroud)

http://coliru.stacked-crooked.com/a/cb6604b81083393f

那么哪个编译器是对的?还是未指明?

这很容易克服gcc构建错误:

  1. 使用括号而不是括号

    ref foo(ref x) {
      return ref(x);
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 通过命名返回值

    ref foo(ref x) {
      ref ret{x};
      return ret;
    }
    
    Run Code Online (Sandbox Code Playgroud)

选项1.打破统一初始化,选项2.添加无用的代码行.

类似的问题在这里已经解决了: 为什么我不能在初始化列表中使用统一初始化初始化引用?

但是提到的pr50025在gcc 4.9中是固定的.

我知道上面的代码示例是没用的,但我故意过度简化它以指出问题.在现实生活中,代码问题可以隐藏在通用函数中,例如:

#include <utility>
template …
Run Code Online (Sandbox Code Playgroud)

gcc reference clang uniform-initialization c++11

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