在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在编译时是否是一个stl容器。 我有以下一些代码: struct is_cont{}; struct not_cont{}; template <typename T> struct is_cont { typedef not_cont result_t; }; 但我不知道如何为std::vector<T,Alloc>, deque<T,Alloc>, set<T,Alloc,Comp>等创build必要的特化。
前提: 在玩了各种各样的模板之后,我意识到,实现任何超出微不足道的元编程任务的东西都将变得非常麻烦。 特别是,我发现自己希望有一种方法来执行generics操作,比如迭代 , 分割 , 循环等 std::for_each方式,等等。 在看了C ++和Beyond 2012 的Andrei Alexandrescu关于static if从C语言中借用一个构造)的愿望之后,我感觉到某种static for也会变得方便 – 我感觉更多这些static结构可以带来好处。 所以我开始想知道是否有一种方法来实现类似于 variadic模板函数( 伪代码 )的参数包: template<typename… Ts> void my_function(Ts&&… args) { static for (int i = 0; i < sizeof…(args); i++) // PSEUDO-CODE! { foo(nth_value_of<i>(args)); } } 在编译时会翻译成这样的内容: template<typename… Ts> void my_function(Ts&&… args) { foo(nth_value_of<0>(args)); foo(nth_value_of<1>(args)); // … foo(nth_value_of<sizeof…(args) […]
在这个答案中,我定义了一个基于types的is_arithmetic属性的模板: template<typename T> enable_if_t<is_arithmetic<T>::value, string> stringify(T t){ return to_string(t); } template<typename T> enable_if_t<!is_arithmetic<T>::value, string> stringify(T t){ return static_cast<ostringstream&>(ostringstream() << t).str(); } dyp表明 ,而不是该types的is_arithmetic属性,是否为该types定义了to_string是模板select条件。 这显然是可取的,但我不知道这样说: 如果未定义std::to_string则使用ostringstream重载。 声明to_string条件很简单: template<typename T> decltype(to_string(T{})) stringify(T t){ return to_string(t); } 这是与我无法弄清楚如何构build的标准相反的。 这显然不起作用,但希望它传达了我想要构build的东西: template<typename T> enable_if_t<!decltype(to_string(T{})::value, string> (T t){ return static_cast<ostringstream&>(ostringstream() << t).str(); }
是否有可能编写一个模板来改变行为取决于某个成员函数是否定义在一个类上? 以下是我想写的一个简单例子: template<class T> std::string optionalToString(T* obj) { if (FUNCTION_EXISTS(T->toString)) return obj->toString(); else return "toString not defined"; } 所以,如果class T有toString()定义,那么它使用它; 否则,它不。 我不知道怎么做的神奇的部分是“FUNCTION_EXISTS”部分。