出于内省的目的,有时我想自动为类型或类似的东西分配序列号.
不幸的是,模板元编程本质上是一种功能语言,因此缺乏实现这种计数器的全局变量或可修改状态.
或者是吗?
按请求的示例代码:
#include <iostream>
int const a = counter_read;
counter_inc;
counter_inc;
counter_inc;
counter_inc;
counter_inc;
int const b = counter_read;
int main() {
std::cout << a << ' ' << b << '\n'; // print "0 5"
counter_inc_t();
counter_inc_t();
counter_inc_t();
std::cout << counter_read << '\n'; // print "8"
struct {
counter_inc_t d1;
char x[ counter_read ];
counter_inc_t d2;
char y[ counter_read ];
} ls;
std::cout << sizeof ls.x << ' ' << sizeof ls.y << '\n'; // print "9 …Run Code Online (Sandbox Code Playgroud) 鉴于所有这三个函数,这个调用是不明确的.
int f( int );
int f( int && );
int f( int const & );
int q = f( 3 );
Run Code Online (Sandbox Code Playgroud)
删除f( int )导致Clang和GCC更喜欢左值引用而不是左值引用.但是,删除任一引用过载都会导致模糊不清f( int ).
过载分辨率通常是根据严格的部分排序来完成的,但int似乎相当于两个彼此不相等的东西.这里的规则是什么?我似乎记得有关此问题的缺陷报告.
在未来的标准中是否有int &&可能优先考虑int?引用必须绑定到初始化程序,而对象类型不受约束.因此,在我之间超载T并且T &&可以有效地表示"如果我已获得所有权,则使用现有对象,否则复制".(这类似于纯通的价值,但移动节省的开销).由于这些编译器目前的工作,这必须通过重载来完成T const &和T &&,并明确复制.但我甚至不确定这是严格的标准.
C++ 11允许使用说明constexpr符声明的函数用于常量表达式,例如模板参数.对于允许的内容有严格的要求constexpr; 本质上这样的函数只包含一个子表达式,而不包含任何其他子表达式.(编辑:这在C++ 14中是放松的,但问题是.)
为什么要求关键字?得到了什么?
它确实有助于揭示接口的意图,但它不会通过保证函数在常量表达式中可用来验证该意图.编写constexpr函数后,程序员必须仍然:
与揭示意图相反,装饰功能constexpr可能会增加错误的安全感,因为在忽略中心语义约束的同时检查了切向句法约束.
简而言之:如果constexpr函数声明仅仅是可选的,那么对语言会有什么不良影响吗?或者对任何有效的程序都会有任何影响吗?
std::declval是一个编译时实用程序,用于构造表达式以确定其类型.它的定义如下:
template< class T >
typename std::add_rvalue_reference<T>::type declval() noexcept;
Run Code Online (Sandbox Code Playgroud)
这不会更简单吗?
template< class T >
T declval() noexcept;
Run Code Online (Sandbox Code Playgroud)
参考返回类型的优点是什么?不应该被称为declref?
我找到的最早的历史例子是n2958,它调用函数value()但总是返回一个引用.
注意,操作数decltype不需要具有可访问的析构函数,即它没有在语义上被检查为完整表达式.
template< typename t >
t declprval() noexcept;
class c { ~ c (); };
decltype ( declprval< c >() ) * p = nullptr; // OK
Run Code Online (Sandbox Code Playgroud) 如何做这项工作?如何实现C99/C++ 11可变参数宏以根据给出多少参数来扩展到不同的东西?
常用的路径分隔符有两种:Unix正斜杠和DOS反斜杠.安息吧,经典的Mac冒号.如果在#include指令中使用,它们是否符合C++ 11,C++ 03和C99标准的规则?
在驳斥了内置运算符不参与重载决策的概念之后,我正在仔细阅读第13.5节,并注意到没有任何部分operator->*.它只是一个通用的二元运算符.
它的弟兄operator->,operator*和operator[],都要求有非静态成员函数.这排除了通常用于从对象获得引用的操作符的自由函数重载的定义.但不常见的operator->*是遗漏了.
特别是,operator[]有许多相似之处.它是二进制的(它们错过了使它成为n-ary的黄金机会),它接受左侧的某种容器和右侧的某种定位器.除了禁止免费功能外,其特殊规则部分13.5.5似乎没有任何实际效果.(这种限制甚至排除了对交换性的支持!)
因此,例如,这是完全合法的:
#include <utility>
#include <iostream>
using namespace std;
template< class T >
T &
operator->*( pair<T,T> &l, bool r )
{ return r? l.second : l.first; }
template< class T >
T & operator->*( bool l, pair<T,T> &r ) { return r->*l; }
int main() {
pair<int, int> y( 5, 6 );
y->*(0) = 7;
y->*0->*y = …Run Code Online (Sandbox Code Playgroud) C++根据strftime需要定义时间格式化函数,这需要struct tm"分解时间"记录.但是,C和C++ 03语言没有提供线程安全的方法来获取这样的记录; struct tm整个计划只有一位大师.
在C++ 03中,这或多或少都可以,因为该语言不支持多线程; 它只支持支持多线程的平台,然后提供像POSIX这样的设施localtime_r.
C++ 11还确定了新的时间公用事业,与非破旧的接口time_t类型,这是什么会被用来重新初始化全局struct tm.但获得一个time_t不是问题.
我错过了什么或者这项任务是否还需要依赖POSIX?
编辑:这是一些解决方法代码.它保持与::localtime_r提供仅提供的单线程环境的多线程环境的兼容性std::localtime.它可以很容易地适应检查其它功能,如posix::localtime_r或::localtime_s或什么都有,你.
namespace query {
char localtime_r( ... );
struct has_localtime_r
{ enum { value = sizeof localtime_r( std::declval< std::time_t * >(), std::declval< std::tm * >() )
== sizeof( std::tm * ) }; };
template< bool available > struct safest_localtime {
static std::tm *call( std::time_t …Run Code Online (Sandbox Code Playgroud) 我想finally在我的C++程序中实现一个块,如果不是原生设施,那么该语言肯定有工具可以实现.我想知道最好的方法是什么?
我正在评论一个线程本地存储很好的答案,并回忆起关于异常的另一个信息性讨论
throw块中执行环境的唯一特殊之处在于rethrow引用了异常对象.
将两个和两个放在一起,不会在其主函数的函数catch块中执行整个线程,并将其与线程本地存储一起使用?
虽然很慢,但似乎工作正常.这是小说还是很有特色?还有另一种解决问题的方法吗?我最初的前提是否正确?get_thread您的平台会产生什么样的开销?优化的潜力是什么?
#include <iostream>
#include <pthread.h>
using namespace std;
struct thlocal {
string name;
thlocal( string const &n ) : name(n) {}
};
struct thread_exception_base {
thlocal &th;
thread_exception_base( thlocal &in_th ) : th( in_th ) {}
thread_exception_base( thread_exception_base const &in ) : th( in.th ) {}
};
thlocal &get_thread() throw() {
try {
throw;
} catch( thread_exception_base &local ) {
return local.th;
}
}
void print_thread() {
cerr << get_thread().name …Run Code Online (Sandbox Code Playgroud)