假设我们有一个带有非类型参数的模板函数,const char *如下所示:
template <const char * MESSAGE> void print() {
std::cout << MESSAGE << '\n';
}
Run Code Online (Sandbox Code Playgroud)
使用此模板不会像日志那样成为MESSAGE可以在编译时推断出来的问题,因此以下用法是合法的:
namespace {
char namespace_message[] = "Anonymous Namespace Message";
constexpr char namespace_constexpr_message[] = "Anonymous Namespace Constexpr Message";
}
char message[] = "Message";
constexpr char constexpr_message[] = "Constexpr Message";
int main()
{
print<namespace_message>();
print<namespace_constexpr_message>();
print<message>();
print<constexpr_message>();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但下面的那些不是(见这里):
namespace {
const char namespace_const_message[] = "Anonymous Namespace Const Message";
}
const char const_message[] = "Const Message";
int …Run Code Online (Sandbox Code Playgroud) 有没有办法实现自定义类型限定符(类似于const)?我想只允许函数调用具有相同资格的函数中具有相同资格的函数.
假设我会:
void allowedFunction();
void disallowedFunction();
//Only allowed to call allowed functions.
void foo()
{
allowedFunction();
disallowedFunction(); //Cause compile time error
}
//Is allowed to call any function it wants.
void bar()
{
allowedFunction();
disallowedFunction(); //No error
}
Run Code Online (Sandbox Code Playgroud)
我想这样做的原因是因为我想确保在特定线程上调用的函数只调用实时安全函数.由于许多应用程序需要硬实时安全线程,因此在编译时使用某种方法检测锁定将保证我们不会发生许多难以检测的运行时错误.
我正在尝试创建一个C源代码,无论目标系统的字节顺序如何,它都能正确处理I/O.
我选择了"little endian"作为我的I/O约定,这意味着,对于大端CPU,我需要在写入或读取时转换数据.
转换不是问题.我面临的问题是检测字节序,最好是在编译时(因为CPU在执行过程中不会改变字节序...).
到目前为止,我一直在使用这个:
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
...
#else
...
#endif
Run Code Online (Sandbox Code Playgroud)
它被记录为GCC预定义的宏,而Visual似乎也理解它.
但是,我收到报告说某些big_endian系统(PowerPC)的检查失败了.
所以,我正在寻找一个万无一失的解决方案,确保无论编译器和目标系统如何都能正确检测到字节顺序.好吧,他们中的大多数至少......
[编辑]:提出的大多数解决方案都依赖于"运行时测试".编译期间编译器有时可以正确评估这些测试,因此不会产生实际的运行时性能.
然而,用某种<< if (0) { ... } else { ... }>> 分支是不够的.在当前的代码实现中,变量和函数声明依赖于big_endian检测.使用if语句无法更改这些内容.
嗯,显然,有后备计划,即重写代码......
我宁愿避免这种情况,但是,它看起来像是一个越来越少的希望......
[编辑2]:我通过深度修改代码测试了"运行时测试".尽管他们正确地完成了工作,但这些测试也会影响性能.
我期待着,因为测试具有可预测的输出,编译器可以消除坏分支.但不幸的是,它并不是一直有效.MSVC是一个很好的编译器,并且成功地消除了坏分支,但是GCC的结果是混合的,这取决于版本,测试类型,以及对64位比对32位的影响更大.
真奇怪.而且这也意味着无法确保编译器处理运行时测试.
编辑3:这些天,我正在使用编译时常量联合,期望编译器将其解析为明确的是/否信号.它运作得很好:https: //godbolt.org/g/DAafKo
如何将编译时间戳信息插入到使用Visual C++ 2005构建的可执行文件中?我希望能够在执行程序时输出类似的内容:
这个版本XXXX编译为dd-mm-yy,hh:mm.
其中日期和时间反映了项目建立的时间.它们不应随着程序的每次连续调用而改变,除非它被重新编译.
我正在开发一个可以选择使用闭源框架的开源项目.如果闭源框架包含在项目中,则会有其他功能.但是,如果框架未包含在项目中,则项目仍应正确编译.
如果框架包含在项目中,如何在编译时检查?
基本上,我想做这样的事情:
#ifdef _MY_FRAMEWORK_EXISTS
#import <MyFramework/MyFramework.h>
#endif
Run Code Online (Sandbox Code Playgroud)
我已经看过2年前的老问题,就像这个问题一样,但没有答案浮出水面,所以我现在可能会遗漏一些新东西.
我不想在运行时通过检查NSClassFromString(),因为当我尝试导入时它将在编译时失败MyFramework并且它不存在.
我需要在编译时检查一些整数素数(将布尔值作为模板参数).
我写的代码做得很好:
#include <type_traits>
namespace impl {
template <int n, long long i>
struct PrimeChecker {
typedef typename std::conditional<
(i * i > n),
std::true_type,
typename std::conditional<
n % i == 0,
std::false_type,
typename PrimeChecker<n, (i * i > n ) ? -1 : i + 1>::type
>::type
>::type type;
};
template <int n>
struct PrimeChecker<n, -1> {
typedef void type;
};
} // namespace impl
template<int n>
struct IsPrime {
typedef typename impl::PrimeChecker<n, 2>::type type;
};
template<>
struct IsPrime<1> …Run Code Online (Sandbox Code Playgroud) 基本上我很好奇,如果代码如下:
let myCollection = Data.SomeCollection.fromList [1, 2, foo]
Run Code Online (Sandbox Code Playgroud)
实际上是在运行时看起来是什么样的,并创建链接列表作为创建SomeCollection-or 的中间步骤,如果这只是语法上的便利,并且编译器避免在编译的代码中创建列表?
如果这是一个愚蠢的问题,请道歉,但自从学习一些Haskell以来,我一直想知道.
在下面的示例中,我希望在编译时被告知,从 long 到 int 的转换会更改值,就像我不使用用户定义的文字时所做的那样。
#include <cassert>
constexpr int operator "" _asInt(unsigned long long i) {
// How do I ensure that i fits in an int here?
// assert(i < std::numeric_limits<int>::max()); // i is not constexpr
return static_cast<int>(i);
}
int main() {
int a = 1_asInt;
int b = 99999999999999999_asInt; // I'd like a warning or error here
int c = 99999999999999999; // The compiler will warn me here that this isn't safe
}
Run Code Online (Sandbox Code Playgroud)
我可以找出几种获得运行时错误的方法,但我希望有某种方法可以使其成为编译时错误,因为据我所知,所有元素都可以在编译时已知。
我们使用Hudson来构建我们的项目,Hudson在编译时方便地定义了像"%BUILD_NUMBER%"这样的环境变量.
我想在代码中使用该变量,因此我们可以在运行时记录这是什么构建.但是我不能做System.Environment.GetEnvironmentVariable,因为那是访问运行时环境,我想要的是这样的:
#define BUILD_NUM = %BUILD_NUMBER%
Run Code Online (Sandbox Code Playgroud)
要么
const string BUILD_NUM = %BUILD_NUMBER%
Run Code Online (Sandbox Code Playgroud)
除了我不知道语法.有人可以指点我正确的方向吗?谢谢!
compile-time ×10
c++ ×6
templates ×2
c ×1
c# ×1
c++11 ×1
endianness ×1
execution ×1
frameworks ×1
haskell ×1
ios ×1
objective-c ×1
polymorphism ×1
qualifiers ×1
string ×1
visual-c++ ×1