我需要一个types特征,如果给定的types是从任何东西派生的,那么这个特征将是真的,否则就是假的。 例如: template<class T> struct is_inherit //… logic of inheritance detection ; template<class T> void AppLogic(){ if constexpr(is_inherit<T>::value) { puts("T has base"); //… } else { puts("T doesn't have base"); //… } } struct A {}; struct C {}; struct B: C {}; int main() { AppLogic<A>(); // print: T doesn't have base AppLogic<B>(); // […]
在C ++ 17中,实现一个overload(fs…)函数是很简单的,给定任意数量的参数fs…满足FunctionObject ,返回一个新的函数对象 ,其行为类似于fs…的重载。 例: template <typename… Ts> struct overloader : Ts… { template <typename… TArgs> overloader(TArgs&&… xs) : Ts{forward<TArgs>(xs)}… { } using Ts::operator()…; }; template <typename… Ts> auto overload(Ts&&… xs) { return overloader<decay_t<Ts>…>{forward<Ts>(xs)…}; } int main() { auto o = overload([](char){ cout << "CHAR"; }, [](int) { cout << "INT"; }); o('a'); // […]
我们能否将可变参数模板参数限制在某种types? 即,实现这样的事情(当然不是真正的C ++): struct X {}; auto foo(X… args) 这里我的意图是有一个接受可变数量的X参数的函数。 我们最近的是这样的: template <class… Args> auto foo(Args… args) 但是这接受任何types的参数。
auto模板参数有哪些优点(可能)会在C ++ 17中引入? 当我想实例化模板代码时,它只是auto扩展吗? auto v1 = constant<5>; // v1 == 5, decltype(v1) is int auto v2 = constant<true>; // v2 == true, decltype(v2) is bool auto v3 = constant<'a'>; // v3 == 'a', decltype(v3) is char 我还从这个语言function中获得了什么?
我使用cppreference阅读了C ++中的枚举声明。 然后我做了Enum类,并检查它是否是类types或不使用std::is_class 。 #include <iostream> enum class Enum { red = 1, blue, green }; int main() { std::cout << std::boolalpha; std::cout << std::is_class<Enum>::value << '\n'; } 然后我编译并运行在Linux平台上的G ++编译器,它打印出false值。 那么是不是类的types? 如果枚举是一个类的types,那么为什么我得到错误的价值?
C ++ 17引入了一个名为std::scoped_lock的新的锁类。 从文档看,它看起来类似于已经存在的std::lock_guard类。 有什么区别,我应该什么时候使用它?
我有以下一段代码: template <typename, typename> struct AAA{}; template<typename …Args> void f(AAA<Args…> *) {} int main() { f<int, int>(nullptr); } 此代码导致编译错误。 当使用g++ -std=c++1z编译时,错误如下所示: prog.cc: In function 'int main()': prog.cc:8:24: error: no matching function for call to 'f<int, int>(std::nullptr_t)' f<int, int>(nullptr); ^ prog.cc:5:6: note: candidate: template<class … Args> void f(AAA<Args …>*) void f(AAA<Args…> *) {} ^ prog.cc:5:6: note: […]
我已经编译并在C ++ 17编译器(Coliru)中运行以下程序。 在程序中,我宣布了一个externvariables,但没有定义它。 但是,编译器不会给出链接器错误 。 #include <iostream> extern int i; // Only declaration int func() { if constexpr (true) return 0; else if (i) return i; else return -1; } int main() { int ret = func(); std::cout<<"Ret : "<<ret<<std::endl; } 为什么编译器不提供链接器错误?
标准委员会于3月21 日投票批准了P0174中提出的std::iterator的弃用 : 对于读者来说,空的参数的长序列对于读者来说要简单得多,而不是简单地在类定义本身中提供预期的types定义,这是当前工作草案采用的方法,遵循C ++ 14中设置的模式 鼓励从std::iteratorinheritancePre-C ++ 17,从迭代器样板实现中移除繁琐的代码。 但是,弃用将需要这些东西之一: 迭代器样板现在需要包含所有必需的typedef 使用迭代器的algorithm现在需要使用auto而不是依赖迭代器来声明types Loki Astaribuild议 std::iterator_traits可以更新为无需inheritancestd::iterator 有人可以启发我,我应该期望哪些选项,因为我devise的自定义迭代器与C + + 17兼容性的眼睛?
cppreference †指出: 具有普通默认构造函数的对象可以通过在任何适当alignment的存储上使用reinterpret_cast来创build,例如,在使用std::malloc分配的std::malloc 。 这意味着以下是明确的代码: struct X { int x; }; alignas(X) char buffer[sizeof(X)]; // (A) reinterpret_cast<X*>(buffer)->x = 42; // (B) 三个问题如下: 那个报价是正确的吗? 如果是的话,那么X的使用寿命到了什么时候? 如果在线(B) ,它是否被视为获取存储的本身? 如果在线(A) ,如果在(A)和(B)之间有一个分支会有条件地构build一个X或其他吊舱, Y ? 在这方面,C ++ 11和C ++ 1z之间有什么变化吗? †请注意,这是一个旧的链接。 这个问题的措辞已经改变了。 它现在写道: 然而,与C不同的是,具有简单默认构造函数的对象不能通过简单地重新解释适当alignment的存储来创build,例如使用std::malloc分配的std::malloc :placement-new需要正式引入一个新对象,并避免潜在的未定义行为。