C++ 1z将引入"constexpr if" - 如果将根据条件删除其中一个分支.似乎合理有用.
但是,没有constexpr关键字是不可能的?我认为在编译期间,编译器应该知道编译时间是否已知.如果是,即使是最基本的优化级别也应该删除不必要的分支.
例如(参见godbolt:https://godbolt.org/g/IpY5y5 ):
int test() {
const bool condition = true;
if (condition) {
return 0;
} else {
// optimized out even without "constexpr if"
return 1;
}
}
Run Code Online (Sandbox Code Playgroud)
Godbolt探险家表示,即使是带有-O0的gcc-4.4.7也没有编译"返回1",所以它实现了constexpr所承诺的.显然,当条件是constexpr函数的结果时,这样的旧编译器将无法这样做,但事实仍然存在:现代编译器知道条件是否为constexpr,并且不需要我明确地告诉它.
所以问题是:
为什么"constexpr if"需要"constexpr"?
请考虑以下代码:
#include <iostream>
#include <type_traits>
template<typename T> class MyClass
{
public:
MyClass() : myVar{0} {;}
void testIf() {
if (isconst) {
myVar;
} else {
myVar = 3;
}
}
void testTernary() {
(isconst) ? (myVar) : (myVar = 3);
}
protected:
static const bool isconst = std::is_const<T>::value;
T myVar;
};
int main()
{
MyClass<double> x;
MyClass<const double> y;
x.testIf();
x.testTernary();
y.testIf(); // <- ERROR
y.testTernary(); // <- ERROR
return 0;
}
Run Code Online (Sandbox Code Playgroud)
对于x(非常量),没有问题.但是,即使在编译时知道if/else中的条件,y(const数据类型)也会导致错误.
是否有可能在编译时不编译错误条件?
最近,我修改了一些if constexpr到if我constexpr功能,发现他们仍然正常工作,并能进行评估时,编译时间.这是一个最小的案例:
template<int N>
constexpr bool is_negative()
{
if constexpr (N >= 0) return false;
else return true;
}
int main()
{
constexpr bool v = is_negative<1>();
}
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,N必须在编译时知道因为它是非类型模板参数,所以if constexpr在这里工作正常.然而,这是一个constexpr功能,因此,IIRC,它是可以让即使我更换一个返回值if constexpr有if:
template<int N>
constexpr bool is_negative()
{
if (N >= 0) return false;
else return true;
}
int main()
{
constexpr bool v = is_negative<1>();
}
Run Code Online (Sandbox Code Playgroud)
从cppref来看,所有的要求A constexpr function …
考虑一个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) 我想为STL容器设计一个打印功能,包括:std::vector, std::map, std::unodered_map, std::set, std::unordered_set, std::list....
理想的函数如下所示:
template<typename T>
void Show(const T& t)
{
if (istype(t, std::vector))
{
// here is a presudo code
// print vector
for (auto i: t) cout << i << endl;
}
else if (istype(t, std::unordered_map))
{
// print unordered_map
}
else
{ }
}
Run Code Online (Sandbox Code Playgroud)
我认为问题发生在 istype()
我知道有一些功能std::is_same可以做到这一点。
但是好像只能操作int或者float不能操作std::vector,你能帮帮忙吗?
这是我的函数的代码:
#include <iostream>
#include <type_traits>
#include <algorithm>
template <typename Head, typename ... Args>
std::common_type_t<Head, Args...> mx(Head n, Args ... args)
{
if (sizeof ... (args) == 0)
return n;
else
return std::max(n, mx(args ...));
}
int main()
{
std::cout << mx(3, 4, 5);
}
Run Code Online (Sandbox Code Playgroud)
我遇到编译错误:
main.cpp:在 'std::common_type_t<Head, Args ...> mx(Head, Args ...) 的实例化中 [with Head = int; 参数 = {}; std::common_type_t<Head, Args ...> = int]': main.cpp:11:24:
从 'std::common_type_t<Head, Args ...> mx(Head, Args ...) 递归地需要[头= int; 参数 = {int}; std::common_type_t<Head, Args …
我正在使用 C++ 和 g++(版本 13.2.1),并且我正在创建一个Determinant<m>接受std::array<std::array<int,m>,m>参数类型并返回该矩阵的行列式的函数。
以下是我写的代码。
\n行列式:
\ntemplate <int m>\nint Determinant(std::array<std::array<int,m>,m> arr){\n\n if(m == 2){\n return arr[0][0]*arr[1][1] - arr[0][1]*arr[1][0];\n }else if(m >2){\n int ans = 0;\n for(int i =0;i < m;i++){\n ans += arr[0][i]*Determinant<m-1>(slc<m,m>( arr,i,0 ))*(i%2 ? 1:-1);\n }\n return ans;\n }else{\n return -1;\n\n }\n }\nRun Code Online (Sandbox Code Playgroud)\nslc :返回一个切片(不是真正的切片,只是删除一行和一列)
\ntemplate <int m, int n>\nstd::array<std::array<int,(n-1)>,(m-1)> slc(std::array<std::array<int,n>,m> arr, int i,int j){\n std::array<std::array<int,(n-1)>,(m-1)> ans;\n\n for(int x = 0;x < m;x ++){\n for (int y = …Run Code Online (Sandbox Code Playgroud) 为什么这段代码在编译时出错?我对“ ”的了解(以及这个)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正在编译。
我想计算提供给 function 的任意数量的参数的总和sum。假设给予函数的整数将满足operator+.
如果我注释掉该函数sum()(没有参数的函数),则代码无法编译。如果我取消注释,代码会编译并运行,但永远不会命中 function sum()。
我似乎无法理解为什么我们需要有sum()功能,因为我正在使用条件sizeof...(Args)
如果有人能帮助我理解这一点,我会非常感激吗?
/*
int sum()
{
std::cout << "Sum with 0 Args" << std::endl;
return 0;
}
*/
template <typename T, typename...Args>
T sum(T first, Args...args)
{
// std::cout << sizeof...(Args) << std::endl;
if (sizeof...(Args) != 0)
{
return first + sum(args...);
}
else
{
std::cout << "Found 0 args" << std::endl;
return first;
}
}
int main()
{
std::cout << sum(1, 2, 3) …Run Code Online (Sandbox Code Playgroud) c++ ×9
c++17 ×4
if-constexpr ×4
templates ×4
constexpr ×3
c++14 ×1
compilation ×1
compile-time ×1
determinants ×1
if-statement ×1
matrix ×1
recursion ×1