假设我有一个在其构造函数中使用布尔值的类,并且如果调用不同的函数,则依赖于布尔值.
class MyClass {
MyClass(bool is_second)
{
common_code();
if (!is_second)
first_constructor();
else
second_constructor();
}
};
Run Code Online (Sandbox Code Playgroud)
我是C++ 17的新手,我想知道是否可以使用模板编程来编写这个逻辑if constexpr.api是这样的:
MyClass<> obj_calls_first_const;
MyClass<is_second_tag> obj_calls_second_const;
Run Code Online (Sandbox Code Playgroud) 考虑一个func非常重要的功能模板.它可以用T=Type1其他类型实例化.部分功能逻辑依赖于T它的实例化.
可以明确地使用if constexpr(代码B)或使用香草if代替(代码A),而编译器可能优化代码.
但是,我想知道,没有constexpr(代码A)的实现有何不同?编译器是否能够if在实例化时检测(在代码A中)哪个分支在编译时使用?可它仍然(换码)生成代码效率不高?
代码A. 没有 if constexpr:
template<class T>
void func(T argument)
{
// some general type-independent logic
if (std::is_same<Type1,T>::value)
{
// do something
}
else
{
// do something else
}
// some general type-independent logic
}
Run Code Online (Sandbox Code Playgroud)
代码B. 用 if constexpr:
template<class T>
void func(T argument)
{
// some general type-independent logic
if constexpr (std::is_same<Type1,T>::value)
{
// …Run Code Online (Sandbox Code Playgroud) 在以下 C++20 函数模板中:
template<int i>
void f() {
if constexpr (i == 1)
g();
else if constexpr (i == 2)
h();
else
??? // <--error
}
Run Code Online (Sandbox Code Playgroud)
有什么我们可以写的东西,???这样f<3>()在编译时调用就会失败?
假设我有一个带有两个参数的函数,其中第一个参数是动态的,但第二个参数始终是编译时已知的常量:
uint8_t convert_bcd(uint8_t num, uint8_t mask) {
uint8_t result = mask & 0x0F & num;
if constexpr ((mask & 0xF0) != 0) // mask is known at compile time, can be optimized
result += 10 * ((mask & 0xF0 & num) >> 4);
return result;
}
Run Code Online (Sandbox Code Playgroud)
用法示例
uint8_t result1 = convert_bcd(data[0], 0x7F);
uint8_t result2 = convert_bcd(data[1], 0x3F);
Run Code Online (Sandbox Code Playgroud)
我想内联此函数(如果可能)并告诉编译器 if 条件(仅涉及始终恒定的第二个参数)可以在编译时解析。
我对inline//以及如何在我的场景中const应用constexpr它们以尽可能优化功能感到困惑。
在 C++ 中执行此操作的正确惯用方法是什么?
鉴于正在检查的条件变量已标记为 ,以下代码片段在功能上是否等效constexpr?
此外,这是模板化上下文中的正确用法if constexpr还是预期的应用程序。
constexpr bool kOn = false;
// Snippet 1
if (kOn) { return true; }
// Snippet 2
if constexpr (kOn) { return true; }
Run Code Online (Sandbox Code Playgroud) 我正在尝试比较constexpr-if语句中的函数参数.
这是一个简单的例子:
constexpr bool test_int(const int i) {
if constexpr(i == 5) { return true; }
else { return false; }
}
Run Code Online (Sandbox Code Playgroud)
但是,当我用GCC 7使用以下标志编译它时:
g++-7 -std=c++1z test.cpp -o test
我收到以下错误消息:
test.cpp: In function 'constexpr bool test_int(int)':
test.cpp:3:21: error: 'i' is not a constant expression
if constexpr(i == 5) { return true; }
Run Code Online (Sandbox Code Playgroud)
但是,如果我test_int用不同的功能替换:
constexpr bool test_int_no_if(const int i) { return (i == 5); }
Run Code Online (Sandbox Code Playgroud)
然后以下代码编译没有错误:
int main() {
constexpr int i = 5;
static_assert(test_int_no_if(i));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我不明白为什么constexpr-if版本无法编译,特别是因为static_assert工作正常. …
我有一个模板函数,使用if constexpr诸如以下命令检查模板参数的类型
template <typename T>
bool something(T arg) {
if constexpr (std::is_integral_v<T>) {
return true;
} else {
// What can I write here so that something<double>(0.0) does not compile?
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
如果没有if constexprs匹配,如何使代码无法编译?
如果我有一个具有两个模板参数的类,有没有办法在其中一个参数上分支 if constexpr?在下面的示例中,我可以测试两个参数是否匹配,但我想要一种匹配任何版本的 MyTemplateClass 的方法,该版本将 char 作为其第一个参数。
#include <iostream>
#include <type_traits>
template<typename T,int32_t N>
class MyTemplateClass
{
};
template<typename C>
void DoStuff(const C& myObj)
{
if constexpr(std::is_base_of_v<MyTemplateClass<char,64>, C>) // how do I remove the hardcoded 64?
{
// test passed!
}
else
{
static_assert(false);
}
}
int main()
{
MyTemplateClass<char, 64> passesObj;
MyTemplateClass<char, 128> shouldPassObj;
MyTemplateClass<wchar_t, 64> failsObj;
DoStuff(passesObj); // passes correctly
DoStuff(shouldPassObj); // currently fails, want to make pass
DoStuff(failsObj); // correctly fails
}
Run Code Online (Sandbox Code Playgroud) 我试图了解 if constexpr 的实用程序,并想知道以这种方式使用它是否有任何实用程序。
template<bool B>
int fun()
{
if constexpr (B)
return 1;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这个函数是否通过使用 if constexpr 而不是常规 if 进行了根本改变?我认为性能是一样的。我对模板的理解是 if 语句的结果在编译时就已经知道,所以没有区别。
我constexpr在C++ 17中使用此参考链接阅读了该文章.
然后,我制作了C++程序进行测试constexpr:
#include <iostream>
int i = 10;
int func()
{
if constexpr (i == 0)
return 0;
else if (i > 0)
return i;
else
return -1;
}
int main()
{
int ret = func();
std::cout<<"Ret : "<<ret<<std::endl;
}
Run Code Online (Sandbox Code Playgroud)
但是,编译器会出错:
main.cpp: In function 'int func()':
main.cpp:8:25: error: the value of 'i' is not usable in a constant expression
if constexpr (i == 0)
^
main.cpp:4:5: note: 'int i' is not const
int …Run Code Online (Sandbox Code Playgroud) 我编写了以下C++ 17代码:
constexpr bool gDebug = true;
template <typename T> constexpr const T& Select(const bool pCondition, const T& a, const T& b)
{
if constexpr (pCondition)
{
return a;
}
else
{
return b;
}
}
Run Code Online (Sandbox Code Playgroud)
然后我这样打电话:
int c = Select<QString>(gDebug, a, b); // In .cpp
Run Code Online (Sandbox Code Playgroud)
我找到error: ‘pCondition’ is not a constant expression了这if constexpr条线.
为什么?这不应该工作吗?
为什么这段代码在编译时出错?我对“ ”的了解(以及这个)if constexpr表明该else块不应该被编译。
if constexpr (true) {
int a = 10;
} else {
int b = 10
}
Run Code Online (Sandbox Code Playgroud)
错误是:
error: expected ‘,’ or ‘;’ before ‘}’ token
Run Code Online (Sandbox Code Playgroud)
使用的编译器:g++ version 7.5.0
编译时我使用了-std=c++17标志。
PS缺少的';' 是故意的,只是为了检查是否else正在编译。
我有一个简单的递归函数来打印参数包中的每个参数
#include <iostream>
template<typename T, typename... Args>
void printArgs(T first, Args... rest) {
std::cout << first << " ";
if constexpr (sizeof...(rest) > 0) { // doesn't compile without constexpr
printArgs(rest...);
} else {
return;
}
}
int main() {
printArgs(1, 2, "hello");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Q1:为什么程序需要constexpr编译?Q2:条件不应该是吗?因为如果大小是,我再次调用,那么不会是空的?(空着可以吗?)if
sizeof...(rest) > 11printArgsrest
我看到了类似的问题,例如“constexpr if”与“if”的优化 - 为什么需要“constexpr”?,但我不明白这些答案与我的案例有什么关系。