我正在尝试编写一个函数,它根据枚举的运行时值将值的枚举映射到一组类型.我意识到你不能根据枚举的运行时值返回不同的类型,因为编译器不知道要分配多少堆栈空间.但是我正在尝试将其写为constexpr函数,使用新的if-constexpr功能来实现它.
我从clang抱怨我正在使用非法指定的模板参数时收到错误.有谁看到如何实现这个?
编辑:这是一个更容易理解的版本,更简洁地演示我的问题:http: //coliru.stacked-crooked.com/a/2b9fef340bd167a8
旧代码:
#include <cassert>
#include <tuple>
#include <type_traits>
namespace
{
enum class shape_type : std::size_t
{
TRIANGLE = 0u,
RECTANGLE,
POLYGON,
CUBE,
INVALID_SHAPE_TYPE
};
template<std::size_t T>
struct shape {
};
using triangle = shape<static_cast<std::size_t>(shape_type::TRIANGLE)>;
using rectangle = shape<static_cast<std::size_t>(shape_type::RECTANGLE)>;
using polygon = shape<static_cast<std::size_t>(shape_type::POLYGON)>;
using cube = shape<static_cast<std::size_t>(shape_type::CUBE)>;
template<std::size_t A, std::size_t B>
static bool constexpr same() noexcept { return A == B; }
template<std::size_t ST>
static auto constexpr make_impl(draw_mode const dm)
{
if constexpr (same<ST, shape_type::TRIANGLE>()) { …Run Code Online (Sandbox Code Playgroud) 我想使用constexpr bool(useF在下面的示例中)来启用以下代码中的功能.在这里,打电话A::f().另外,我希望在关闭该功能的情况下成为alias-template(a)void.
我试图使用constexpr if语句,但是主体仍在实例化,这会导致编译错误.如果我使用包装器模板(X),正如我预期的那样丢弃了正文,但这对我来说似乎很难看.有没有其他方法可以做到这一点?
constexpr bool useF = false;
struct A {
static void f() {}
};
using a = std::conditional<useF, A, void>::type;
template<typename L>
struct X {
static void h() {
if constexpr(std::is_same<L, A>::value) {
L::f(); // not instantiated, no error
}
}
};
int main() {
if constexpr(useF) {
a::f(); // error!?
}
X<a>::h();
}
Run Code Online (Sandbox Code Playgroud)
我正在使用g ++ - 7.0.1和-std = c ++ 17
有没有办法解决以下问题:
此代码生成C4702警告"无法访问代码"(在VC++ 15.8上/std:c++17)
template <typename T, typename VariantType>
inline bool MatchMonostate( VariantType& variant )
{
SUPPRESS_C4100( variant );
if constexpr ( std::is_same_v<T, std::monostate> )
{
variant = std::monostate();
return true;
}
return false; // !!! unreachable if the above is true !!! => C4702
}
Run Code Online (Sandbox Code Playgroud)
为了抑制C4100'未引用的形式参数'警告,我已经在使用这个技巧了
#define SUPPRESS_C4100(x) ((void)x)
Run Code Online (Sandbox Code Playgroud)
添加的简单想法
else
{
return false;
}
Run Code Online (Sandbox Code Playgroud)
导致警告C4715'并非所有控制路径都返回值'.
在C++ 17中,if constexpr介绍了; 然而,似乎没有switch constexpr(见这里).这是为什么?也就是说,如果一个编译器支持if constexpr,它支持它是否也是微不足道的switch constexpr(最坏的情况是if-then-else-if-etc.链,或多个如果带有一些标志来控制直通)?
同时努力实现if constexpr与requires clause基于如果constexpr和要求,表达了即席概念检查面临着以下问题:
template<class P>
concept TuplePair = requires(P p) {
requires std::tuple_size<P>::value == 2;
std::get<0>(p);
std::get<1>(p);
};
void print(const auto& p) {
if constexpr( TuplePair<decltype(p)> ) {
std::cout << std::get<0>(p) << ", " << std::get<1>(p) << std::endl;
}
else {
std::cout << "else" << std::endl;
}
}
int main() {
// justifiably prints 'else':
print(std::make_tuple(3, 4, 5));
// prints 'else' even though this is a valid TuplePair:
print(std::make_tuple(1, 2));
}
Run Code Online (Sandbox Code Playgroud)
有什么问题if constexpr …
是否可以在 constexpr 上下文中使用“if constexpr”来比较 std::string_view ?以及为什么 is_hello_2 和 is_hello_4 无法编译显示错误:“'s' 不是常量表达式”
static constexpr bool is_hello_1(auto s) {
return s == "hello";
}
static constexpr bool is_hello_2(auto s) {
if constexpr (s == "hello") {
return true;
}
return false;
}
static constexpr auto is_hello_3 = [](auto s) {
return s == "hello";
};
static constexpr auto is_hello_4 = [](auto s) {
if constexpr (s == "hello") {
return true;
}
return false;
};
Run Code Online (Sandbox Code Playgroud)
考虑到主要功能(https://godbolt.org/z/zEcnb8):
int main(int argc, char …Run Code Online (Sandbox Code Playgroud) 我发现许多嵌套的std :: conditional_t难以阅读,所以我选择了一个不同的模式(在自动返回类型的函数上调用decltype):
template<bool is_signed, std::size_t has_sizeof>
auto find_int_type(){
static_assert(sizeof(int)==4);
if constexpr(is_signed){
if constexpr(has_sizeof==4){
return int{};
} else if constexpr (has_sizeof==8){
return std::int64_t{};
} else {
return;
}
} else {
if constexpr(has_sizeof==4){
return (unsigned int){};
}
else if constexpr (has_sizeof==8){
return std::uint64_t{};
} else {
return;
}
}
}
static_assert(std::is_same_v<int, decltype(find_int_type<true, 4>())>);
static_assert(std::is_same_v<unsigned int, decltype(find_int_type<false, 4>())>);
static_assert(std::is_same_v<void, decltype(find_int_type<false, 3>())>);
static_assert(std::is_same_v<void, decltype(find_int_type<false, 5>())>);
static_assert(std::is_same_v<std::int64_t, decltype(find_int_type<true, 8>())>);
static_assert(std::is_same_v<std::uint64_t, decltype(find_int_type<false, 8>())>);
static_assert(std::is_same_v<void, decltype(find_int_type<false, 9>())>);
Run Code Online (Sandbox Code Playgroud)
我的问题是:
有没有更好的办法?
编译这种方式比std :: conditional_t慢(假设我需要实例化的类型比我刚才使用内置类型的示例更广泛).
PS这是一个玩具示例,IRCode我会处理一些更复杂的类型.
我正在编写一个宏,当用于包装像这样的函数调用时:macro(function())返回 a std::optional<T>,其中 T 是函数的返回值。到目前为止它可以工作,但是std::optional<bool>当函数没有返回类型(即它返回void)时,我试图让它返回a时遇到了问题。
问题的核心是编译器尝试评估 if-constexpr 的范围,当函数没有返回类型时,该 if-constexpr 的计算结果为 false。
我尝试使用两个 if-constexpr 和一个 else。我尝试内联所有内容并将其展开几行。我尝试用常量文字替换编译器计算的 constexpr 常量。到目前为止没有任何效果。
我现在拥有的宏如下所示:
#ifndef troy
#define troy(body)[](){\
constexpr auto inner_type_is_void=std::is_same<decltype(body), void>::value;\
using inner_type=std::conditional<inner_type_is_void,bool,decltype(body)>::type;\
try{\
if constexpr (inner_type_is_void) {(body); return std::optional<inner_type>{true};}\
if constexpr (!inner_type_is_void) {return std::optional<inner_type>{(body)};}\
} catch (...){\
return std::optional<inner_type>{};\
}\
}()
#endif
Run Code Online (Sandbox Code Playgroud)
我像这样使用它:
{
auto a=troy(f());
if (!a){
std::cout << "fail" << std::endl;
} else{
std::cout << "success: " << *a << std::endl;
}
}
Run Code Online (Sandbox Code Playgroud)
它在 f 返回一个值时工作,但在不返回时给出编译器错误。此编译器错误是:no …
结合if constexpr一些<type_traits>实体,在 C++17 中,我能够在编译时检查类型。这些技术可以被认为是静态反射吗?还是只是型式检验?例子:
if constexpr (std::is_same_v<T, U>) statement
Run Code Online (Sandbox Code Playgroud)
反射概念是否仅适用于运行时?称之为静态反射是否正确?
为了防止编译器将例如 a 应用于std::vector<T>类似的语句std::cout << u,我想做这样的事情:
if constexpr (std::has_output_operator<U>) {\n std::cout << u;\n}\nRun Code Online (Sandbox Code Playgroud)\n有什么方法可以实现这一目标吗?
\n编辑(澄清)\n我正在研究类似 printf 的函数,它也可以打印 POD 的字符串和向量以及字符串(及其向量)。
\n我想将此功能扩展到任何具有输出运算符的类型。
\n非向量类型的实际格式化是由函数完成的simpleFormat():
// simpleFormat\n// special case for single string\n//\nstd::string simpleFormat(const std::string sFormat, const std::string t) {\n size_t required = snprintf(NULL, 0, sFormat.c_str(), t.c_str());\n char sTemp[required+1];\n sprintf(sTemp, sFormat.c_str(), t.c_str());\n return std::string(sTemp);\n} \n\n// simpleFormat\n// catch for vectors (should not be sent to simpleFormat)\ntemplate<typename T>\nstd::string simpleFormat(const std::string sFormat, const std::vector<T> t) {\n …Run Code Online (Sandbox Code Playgroud) c++ ×10
if-constexpr ×10
c++17 ×6
c++20 ×3
c++-concepts ×1
reflection ×1
string-view ×1
templates ×1
type-traits ×1
visual-c++ ×1