考虑以下代码:
#include <type_traits>
struct T {};
static_assert(std::is_trivially_destructible< T >{});
static_assert(std::is_trivially_default_constructible< T >{});
struct N { ~N() { ; } };
static_assert(!std::is_trivially_destructible< N >{});
static_assert(!std::is_trivially_default_constructible< N >{});
Run Code Online (Sandbox Code Playgroud)
如果满足以下所有条件,则类T的默认构造函数是微不足道的(即不执行任何操作):
- 构造函数不是用户提供的(即,隐式定义或默认)
- T没有虚拟成员函数
- T没有虚拟基类
- T没有使用默认初始值设定项的非静态成员.(自C++ 11以来)
- T的每个直接基都都有一个普通的默认构造函数
- 类类型的每个非静态成员都有一个普通的默认构造函数
正如我所看到的,不依赖于析构函数的琐碎性.
我错过了什么?是clangbug吗?
我找到了一个解决方法:static_assert(__has_trivial_constructor( N ));内置类型特征.有支持clang,gcc及MSVC.
对于is_noexcept_constructible类型特征的家庭也有解决方法.
为什么operator ()不允许无状态仿函数static?无状态lambda对象可转换为指向具有与其相同签名的自由函数的指针operator ().
Stephan T. Lavavej on p.6指出转换为函数指针只是一个operator FunctionPointer()(引用).但是我无法获得与operator ()非成员函数相对应的指针.对于仿函数struct F { void operator () () {} },似乎无法转换&F::operator ()为类型的实例using P = void (*)();.
码:
struct L
{
static
void operator () () const {}
operator auto () const
{
return &L::operator ();
}
};
Run Code Online (Sandbox Code Playgroud)
错误是
重载'operator()'不能是静态成员函数
但operator ()没有超载.
如何确定(在<type_traits>精神上)一种类型是否可以明确转换为另一种类型?例如,我想检查F::explicit operator double const & () const;某些class/ 的存在struct F,但同时,F不应该明确地转换为float或long double(类似pred< double const & >::value && !pred< float >::value && !pred< long double >::value).
注意,std::is_convertible< From, To >::value检查"是否可以使用隐式转换将From转换为To ".但我想确定是否有显式转换运算符.
而且,如果可能的话,"如何确定,类型从可转换为一个,即参考键入要?"?
当我编译#if 0和#if 1下面代码的版本时,如何解释差异:
#include <cstdlib>
struct A
{
explicit A() = default; // explicitly defaulted or deleted constructors are allowed for aggregates (since C++11)
#if 1
private :
#endif
int i;
};
int
main()
{
A a = {};
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
#if 0所有的罚款,编译成功.#if 1编译失败,错误信息:
错误:选择的构造函数在复制初始化中是显式的
表达式A a = {};取决于是否A为aggreagate有什么区别?
如果在两种情况下都没有使用括号,那么函数(模板)的返回类型decltype(auto)和decltype(returning expression)返回类型之间有什么区别expr?
auto f() -> decltype(auto) { return expr; } // 1
auto f() -> decltype(expr) { return expr; } // 2
Run Code Online (Sandbox Code Playgroud)
上面f可以在任何上下文中定义/声明,可以是(成员)函数或(成员)函数模板,甚至是(泛型)lambda.expr可以依赖于任何模板参数.
在第二个版本中,两者expr都是完全相同的表达式,没有额外的括号.
在C++ 14及更高版本中使用第一种或第二种形式可以预期哪些差异?
如果括号到处使用怎么办?
评估编译程序所需的精确最小值-fconstexpr-steps=和-ftemplate-depth=参数的最佳方法是什么?
我目前所做的是对价值的二分法.但是对于真实世界模板加载的程序,它变得非常长,甚至在值的上限上是对数的.
有-v选项-ftime-report,但是即使它们的输出也没有给出关于实际使用的最大模板深度和在评估常量表达式时实际传递的步骤数的任何所需信息.
是否有一个很好的算法实现来计算C++ STL(甚至是boost)中两个范围的卷积?即原型(两个范围的卷积a..b和c..d)的东西:
template< class Iterator >
void convolution(Iterator a, Iterator b, Iterator c, Iterator d);
Run Code Online (Sandbox Code Playgroud)
它修改了a..b范围
boost::optional< T >如果基础类型T是非默认的可构造的,不可复制/可移动的,但我应该做什么来初始化,但是一个实例仍然可以存在?
是否boost::optional由于任何语义原因禁止使用某些成员函数template< typename... Args > boost::optional< T >::construct(Args && ...args),它将所有参数传递给就地operator new完全构造对象(对于非ref类型T)?Variant是具有非成员函数的std::make_shared< T >.
在我看来,我的问题可以通过使用std::unique_ptr/ 解决std::shared_ptr,但在这种情况下我的问题是:"为什么boost::optional进展被冻结?".
如果没有另一个超载(比如,f(T &)或f(volatile T &&)一个(部件)函数模板的)template< typename T > f(T &&);,然后T &&是所谓的转发参考,并且T要么是U,或U &对于一些CV-合格类型U.但是对于成员函数的cv-ref-qualifiers,没有这样的规则.在struct S { void f() && { ; } };一个S::f()总是rvalue-reference限定符.
在通用代码中volatile,如果所有这些函数通常都做同样的事情,那么避免定义4(甚至8,如果我们也考虑限定符)某些成员函数的重载将是非常有用的.
中出现的这种方式的另一个问题,这是不可能的,以限定一个有效的CV-REF-限定符的*this在特定的意义.以下代码不允许确定成员函数的ref限定符operator ()是否&&为&.
#include <type_traits>
#include <utility>
#include <iostream>
#include <cstdlib>
#define P \
{ \
using this_ref = decltype((*this)); \ …Run Code Online (Sandbox Code Playgroud) c++ ×9
c++11 ×4
c++14 ×3
algorithm ×1
auto ×1
boost ×1
c++17 ×1
clang ×1
constexpr ×1
constructor ×1
convolution ×1
decltype ×1
destructor ×1
functor ×1
gcc ×1
lambda ×1
noncopyable ×1
stl ×1
templates ×1