小编Lin*_*gxi的帖子

向上转换空指针会导致未定义的行为

我想知道以下代码是否导致未定义的行为:

#include <cstddef>
#include <cstdio>

struct IA { 
  virtual ~IA() {}
  int a = 0;
};
struct IB {
  virtual ~IB() {}
  int b = 0;
};
struct C: IA, IB {};

int main() {
  C* pc = nullptr;
  IB* pib = pc;
  std::printf("%p %p", (void*)pc, (void*)pib);
}
Run Code Online (Sandbox Code Playgroud)

c++ upcasting nullptr language-lawyer implicit-conversion

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

为什么标准容器使用函数模板而不是非模板Koenig运算符

这个问题的灵感来自于std :: reference_wrapper的问题.让我们说,例如,operator<对于std::vector.它被定义为函数模板

template< class T, class Alloc >
bool operator<( const vector<T,Alloc>& lhs,
                const vector<T,Alloc>& rhs );
Run Code Online (Sandbox Code Playgroud)

因此,拒绝将函数参数隐式转换为相应函数参数的类型(主要是因为其模板性质).这大大降低了它的实用性和便利性std::reference_wrapper.例如,您不能使用std::sortstd::vector<std::reference_wrapper<std::vector<int>>>.

另一方面,只有当operator<定义为非模板Koenig运算符时,才能解决所有问题

template <...>
class vector ... {
  friend bool operator<(const vector& a, const vector& b) {...}
};
Run Code Online (Sandbox Code Playgroud)

我想知道为什么标准库采用了前一种方法而不是这种方法?

c++ standard-library implicit-conversion c++11 reference-wrapper

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

从IEnumerable转换为IEnumerable <object>

我更喜欢使用IEnumerable<object>,对于LINQ扩展方法是定义的,不是IEnumerable,所以我可以使用,例如,range.Skip(2).不过,我也喜欢使用IEnumerable,对于T[]隐式转换为IEnumerable是否T是引用类型或值类型.对于后一种情况,不涉及拳击,这是好的.结果,我能做到IEnumerable range = new[] { 1, 2, 3 }.似乎不可能将两者的优点结合起来.无论如何,IEnumerable当我需要应用LINQ方法时,我选择安顿下来并做一些演员.

这个 SO线程,我开始知道range.Cast<object>()能够完成这项工作.但它会产生性能开销,这在我看来是不必要的.我尝试执行直接编译时强制转换(IEnumerable<object>)range.根据我的测试,它适用于参考元素类型,但不适用于值类型.有任何想法吗?

仅供参考,问题源于 GitHub问题.我使用的测试代码如下:

static void Main(string[] args)
{
    // IEnumerable range = new[] { 1, 2, 3 }; // won't work
    IEnumerable range = new[] { "a", "b", "c" };
    var range2 = (IEnumerable<object>)range;
    foreach (var item in range2)
    {
        Console.WriteLine(item);
    }
}
Run Code Online (Sandbox Code Playgroud)

c# linq arrays ienumerable language-lawyer

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

为什么{}工作而while()不在这里初始化原子对象?

考虑一下代码:

#include <atomic>

struct stru {
  int a{};
  int b{};
};

int main() {
  // Doesn't work: std::atomic<stru> as({});
  std::atomic<stru> as{{}};
}
Run Code Online (Sandbox Code Playgroud)

为直接初始化生成的错误消息如下:

prog.cc: In function 'int main()':
prog.cc:9:26: error: call of overloaded 'atomic(<brace-enclosed initializer list>)' is ambiguous
   std::atomic<stru> as({});
                          ^
In file included from prog.cc:1:0:
/opt/wandbox/gcc-7.2.0/include/c++/7.2.0/atomic:200:17: note: candidate: constexpr std::atomic<_Tp>::atomic(_Tp) [with _Tp = stru]
       constexpr atomic(_Tp __i) noexcept : _M_i(__i) { }
                 ^~~~~~
/opt/wandbox/gcc-7.2.0/include/c++/7.2.0/atomic:196:7: note: candidate: std::atomic<_Tp>::atomic(const std::atomic<_Tp>&) [with _Tp = stru] <deleted>
       atomic(const atomic&) = delete;
   ^~~~~~
Run Code Online (Sandbox Code Playgroud)

我认为这两种形式在这种特殊情况下应该没有区别.为什么会这样?

c++ initialization atomic list-initialization c++14

13
推荐指数
0
解决办法
142
查看次数

为什么一元运算符并不需要完整的类型?

以下代码使用gcc 7.2.0clang 6.0.0编译得很好.

#include <iostream>

struct stru;

void func(stru& s) {
  std::cout << &s << std::endl;
}

int main() {

}
Run Code Online (Sandbox Code Playgroud)

我想知道这是怎么回事.如果stru超载operator&()怎么办?编译器不应该只用一个前向声明来表示struct stru.在我看来,只有std::addressof(s)不完整的类型才行.

c++ operator-overloading addressof incomplete-type c++11

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

std :: allocator <void>的弃用

相关:为什么标准容器需要allocator_type :: value_type作为元素类型?

据说自C++ 17以来已经弃用了以下内容:

template<>
struct allocator<void>;
Run Code Online (Sandbox Code Playgroud)

我想知道它是否已被弃用,因为现在只能使用主模板allocator<void>,或者allocator<void>不推荐使用用例.

如果是后者,我想知道为什么.我认为allocator<void>在指定未绑定到特定类型的分配器时非常有用(所以只需要一些模式/元数据).

c++ memory-management allocator c++-standard-library c++17

12
推荐指数
2
解决办法
1092
查看次数

gcc中的默认构造内联静态随机数引擎

例如,

#include <random>

struct stru {
  //inline static std::mt19937 rnd; Oops!
  inline static std::mt19937 rnd{};  
};

int main() {

}
Run Code Online (Sandbox Code Playgroud)

我发现两者没有语义差异,而clang在编译两者时没有问题.然而,gcc 8.1为第一个产生以下错误:

prog.cc:4:30: error: no matching function for call to 'std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>::mersenne_twister_engine()'
   inline static std::mt19937 rnd;
                              ^~~
In file included from /opt/wandbox/gcc-8.1.0/include/c++/8.1.0/random:49,
                 from prog.cc:1:
/opt/wandbox/gcc-8.1.0/include/c++/8.1.0/bits/random.h:437:11: note: candidate: 'constexpr std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>::mersenne_twister_engine(const …
Run Code Online (Sandbox Code Playgroud)

c++ gcc inline libstdc++ c++17

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

隐式转换如何适用于非类型模板参数?

我猜(某些)隐式转换在传递非类型模板参数时适用.例如,应该有从一个转换intstd::size_t用于表达喜欢std::array<int, 7>.但是,请考虑以下代码:

template <bool>
void f() {
    std::cout << "false\n";
}

template <>
void f<true>() {
    std::cout << "true\n";
}

int main() {
    f<1>();
    f<4>();
    f<0>();
}
Run Code Online (Sandbox Code Playgroud)

我希望int隐式转换到bool这里.但VC,GCC和clang的行为不同.

在VC, ,true,falsefalse打印,这实在是怪我.

在海湾合作委员会,true,true,和false印,这是我的期望.

在clang上,由于语句,代码根本不编译f<4>();.

候选模板被忽略:第一个模板参数的显式指定参数无效

那么,标准对此有何看法?非类型模板参数的隐式转换规则是什么?

c++ templates type-conversion template-specialization implicit-conversion

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

std :: timed_mutex :: try_lock*虚假失败

通过try_lock*,我采取的意思是try_lock(),try_lock_for()try_lock_until().根据cppreference,这三种方法可能只是虚假地失败.以下是从描述中引用的try_lock_for()

与此同时try_lock(),false即使互斥锁在某个时刻未被任何其他线程锁定,也允许此函数虚假失败并返回timeout_duration.

我知道可能会发生虚假的唤醒std::condition_variable及其背后的基本原理.但是,互斥量是什么情况?

c++ multithreading mutex thread-synchronization c++11

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

有关const decltype(x)&的问题

请考虑以下代码:

int a = 1;
const int& b = a;
std::cout << std::is_same<const decltype(b)&, const int&>();
Run Code Online (Sandbox Code Playgroud)

它在clang 3.5上编译,而GCC 4.9给出以下错误:

error: 'const' qualifiers cannot be applied to 'const int&'

根据标准哪一个是正确的?我的猜测是GCC符合标准,就像你不能做到的那样int& const b = a;.

c++ templates metaprogramming decltype language-lawyer

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