我想使用if constexpr而不是标签调度,但我不知道如何使用它.示例代码如下.
template<typename T>
struct MyTag
{
static const int Supported = 0;
};
template<>
struct MyTag<std::uint64_t>
{
static const int Supported = 1;
};
template<>
struct MyTag<std::uint32_t>
{
static const int Supported = 1;
};
class MyTest
{
public:
template<typename T>
void do_something(T value)
{
// instead of doing this
bool supported = MyTag<T>::Supported;
// I want to do something like this
if constexpr (T == std::uint64_t)
supported = true;
}
};
Run Code Online (Sandbox Code Playgroud) c ++ 17提供if constexpr,其中:
condition的值必须是类型的上下文转换的常量表达式
bool.如果值为true,则丢弃statement-false(如果存在),否则,将丢弃statement-true
有没有办法在a- forstatement中使用它?要在编译时展开循环吗?我希望能够做到这样的事情:
template <int T>
void foo() {
for constexpr (auto i = 0; i < T; ++i) cout << i << endl;
}
Run Code Online (Sandbox Code Playgroud) 考虑以下代码。如果我的理解if constexpr是正确的,则else不应编译分支,因此z()不应将其视为错误。
#include <type_traits>
struct Z{};
template<typename T>
void f(T z) {
auto lam = [z]() {
if constexpr(std::is_same<T, Z>::value) {
} else {
z();
}
};
}
int main() {
f(Z{});
}
Run Code Online (Sandbox Code Playgroud)
用clang和gcc编译;但是使用最新的MSVC却没有。不幸的是,goldbolt的MSVC太旧了,但是在我的计算机上使用VS 2017进行了全面更新,结果是cl /std:c++17:
Microsoft (R) C/C++ Optimizing Compiler Version 19.14.26428.1 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
if_constexpr.cpp
if_constexpr.cpp(10): error C2064: term does not evaluate to a function taking 0 arguments
if_constexpr.cpp(16): note: …Run Code Online (Sandbox Code Playgroud) Is it possible to overload the operator new to be constexpr function? Something like:
constexpr void * operator new( std::size_t count );
Run Code Online (Sandbox Code Playgroud)
The reason why would be to execute constexpr function within the overloaded operator body where count argument value would be an input data... As the operator is invoked by:
SomeClass * foo = new SomeClass();
Run Code Online (Sandbox Code Playgroud)
The size of the data type is know at compile time, isn’t it? (count== sizeof(SomeClass)) So the count can be considered …
我用来std::variant指定项目中的实体可能具有的属性类型,并从 cppreference 中偶然发现了以下代码:
std::visit([](auto&& arg)
{
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, int>)
std::cout << "int with value " << arg << '\n';
else if constexpr (std::is_same_v<T, long>)
std::cout << "long with value " << arg << '\n';
else if constexpr (std::is_same_v<T, double>)
std::cout << "double with value " << arg << '\n';
else if constexpr (std::is_same_v<T, std::string>)
std::cout << "std::string with value " << std::quoted(arg) << '\n';
else
static_assert(always_false_v<T>, "non-exhaustive visitor!");
}, w);
Run Code Online (Sandbox Code Playgroud)
always_false_v定义为 …
struct A{
constexpr operator bool()const{ return true; }
};
int main(){
auto f = [](auto v){ if constexpr(v){} };
A a;
f(a);
}
Run Code Online (Sandbox Code Playgroud)
clang 6 接受代码,GCC 8 拒绝它:
$ g++ -std=c++17 main.cpp
main.cpp: In lambda function:
main.cpp:6:37: error: 'v' is not a constant expression
auto f = [](auto v){ if constexpr(v){} };
^
Run Code Online (Sandbox Code Playgroud)
谁是正确的,为什么?
当我根据每个引用获取参数时,都拒绝代码:
struct A{
constexpr operator bool()const{ return true; }
};
int main(){
auto f = [](auto& v){ if constexpr(v){} };
constexpr A a;
f(a);
}
Run Code Online (Sandbox Code Playgroud)
用clang …
是否可以执行以下操作:
template <unsigned majorVer, unsigned minorVer>
class Object
{
public:
if constexpr ((majorVer == 1) && (minorVer > 10))
bool newField;
else
int newInt
};
Run Code Online (Sandbox Code Playgroud)
或者
template <unsigned majorVer, unsigned minorVer>
class Object
{
public:
if constexpr ((majorVer == 1) && (minorVer > 10))
bool newField;
// Nothing other wise
};
Run Code Online (Sandbox Code Playgroud)
使用 C++17?我想根据一些可以在编译时检查的条件来更改类的结构。有没有办法实现这一目标?
这个模板函数f<X>()总是不会被实例化吗?
if constexpr(something false){\n //some template function OR function in template class\n f<X>();\n}\nRun Code Online (Sandbox Code Playgroud)\n\n以下是我的测试(coliru MCVE)。
\n我创建了当且仅当 时fun<S>()才会实例化。\n然后我调用,和。E<S>S!=voidfun<void>()fun<int>()fun<float>()
我相信if constexpr(false)强制 C++ 编译器#1跳过fun<void>().
\n我的countRunner应该++只有2次。
因此,如果我的假设成立,下面的程序将始终在每个编译器和每个设置中打印 2。
\n\n(它为我打印了 2,但仅凭实验并不能证明什么。)
\n\n#include<iostream>\nint countRunner=0;\ntemplate<class T> class E{\n public: static int countIndex;\n public: E(){\n if(false){\n int unused=E::countIndex;\n }\n }\n};\ntemplate<class T> int E<T>::countIndex=countRunner++;\ntemplate<class S> void fun(){\n if constexpr(!std::is_same_v<void,S>){\n E<S> …Run Code Online (Sandbox Code Playgroud) c++ language-lawyer c++17 if-constexpr template-instantiation
我有一系列很长的if constexpr语句,如果没有一个成功,我想触发编译时错误。
具体来说,我有一个抽象语法树,我想将其结果转换为我可能需要的一组特定类型。我有 AsInt()、AsDouble() 等正在工作,但我需要能够根据提供的类型更动态地执行此操作。
就目前情况而言,我已经编写了一个模板化的 As() 成员函数,但它的错误检查很笨拙。具体来说,使用静态断言需要一个笨拙的测试条件。这是一个简化版本:
template <typename T>
T As() {
if constexpr (std::is_same_v<T,int>) return AsInt();
if constexpr (std::is_same_v<T,double>) return AsDouble();
...
if constexpr (std::is_same_v<T,std::string>) return AsString();
static_assert( std::is_same_v<T,int>
|| std::is_same_v<T,double>
|| ...
|| std::is_same_v<T,std::string>,
"Invalid template type for As()" );
}
Run Code Online (Sandbox Code Playgroud)
如果所有条件都失败,是否有更简单的方法来触发静态断言(或等效方法)?
以下代码尝试根据参数包中传递的最后一个参数做出编译时决策。如果参数包参数的数量 > 0,它包含一个比较,然后尝试获取它的最后一个元素。但是,构造的元组是在无效索引处访问的,该索引据称大于最大元组索引(如图所示static_assert)。
如果我这样做怎么可能cnt-1?
#include <cstdio>
#include <concepts>
#include <utility>
#include <tuple>
template <typename... Args>
auto foo(Args&&... args)
{
auto tuple = std::forward_as_tuple(std::forward<Args>(args)...);
constexpr std::size_t cnt = sizeof...(Args);
if constexpr (cnt > 0 && std::same_as<std::remove_cvref_t<std::tuple_element_t<cnt-1, decltype(tuple)>>, int>) {
printf("last is int\n");
} else {
printf("last is not int\n");
}
}
int main()
{
foo(2);
foo();
}
Run Code Online (Sandbox Code Playgroud)
错误:
/opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/tuple: In instantiation of 'struct std::tuple_element<18446744073709551615, std::tuple<> >':
<source>:13:25: required from 'auto foo(Args&& ...) [with Args = {}]' …Run Code Online (Sandbox Code Playgroud) c++ ×10
if-constexpr ×10
c++17 ×8
constexpr ×2
templates ×2
and-operator ×1
class ×1
for-loop ×1
tuples ×1
type-traits ×1