template-meta-programming

“too many template-parameter-lists” error when specializing a member function

谁说我不能喝 提交于 2019-11-29 03:59:37
I would like to define some template member methods inside a template class like so: template <typename T> class CallSometing { public: void call (T tObj); // 1st template <typename A> void call (T tObj, A aObj); // 2nd template <typename A> template <typename B> void call (T tObj, A aObj, B bObj); // 3rd }; template <typename T> void CallSometing<T>::call (T tObj) { std::cout << tObj << ", " << std::endl; } template <typename T> template <typename A> void CallSometing<T>::call (T tObj, A aObj) { std::cout << tObj << ", " << aObj << std::endl; } template <typename T> template <typename A>

How to check if template argument is a callable with a given signature

末鹿安然 提交于 2019-11-29 02:31:45
问题 Basically, what I want to achieve is compile-time verification (with possibly nice error message) that registered callable (either a function, a lambda, a struct with call operator) has correct signature. Example (contents of the static_assert are to be filled): struct A { using Signature = void(int, double); template <typename Callable> void Register(Callable &&callable) { static_assert(/* ... */); callback = callable; } std::function<Signature> callback; }; 回答1: Most of the answers are

Elegantly define multi-dimensional array in modern C++

旧巷老猫 提交于 2019-11-29 00:08:26
问题 Defining multi-dimensional array using the T[][][] syntax is easy. However, this creates a raw array type which doesn't fit nicely into modern C++. That's why we have std::array since C++11. But the syntax to define a multi-dimensional array using std::array is quite messy. For example, to define a three-dimensional int array, you would have to write std::array<std::array<std::array<int, 5>, 5>, 5> . The syntax doesn't scale at all. I'm asking for a fix for this issue. Maybe, this issue

Why can't std::tuple<int> be trivially copyable?

蹲街弑〆低调 提交于 2019-11-28 23:45:22
Built with this online compiler , the following code: #include <iostream> #include <type_traits> #include <tuple> int main() { std::cout << std::is_trivially_copyable<std::tuple<int>>::value << std::endl; std::cout << std::is_trivially_copyable<std::pair<int, int>>::value << std::endl; std::cout << std::is_trivial<std::tuple<int>>::value << std::endl; std::cout << std::is_trivial<std::pair<int, int>>::value << std::endl; return 0; } outputs: 0 0 0 0 I'm getting the same results with Visual Studio 2015. Why is that the case? Is there a valid reason an std::tuple of POD types, let alone a simple

Profiling template metaprogram compilation time

前提是你 提交于 2019-11-28 23:09:32
I'm working on a C++ project with extensive compile-time computations. Long compilation time is slowing us down. How might I find out the slowest parts of our template meta-programs so I can optimize them? (When we have slow runtime computations, I have many profilers to choose from, e.g. valgrind's callgrind tool. So I tried building a debug GCC and profiling it compiling our code, but I didn't learn much from that.) I use GCC and Clang, but any suggestions are welcome. I found profile_templates on Boost's site, but it seems to be thinly documented and require the jam/bjam build system. If

constexpr initialization of array to sort contents

可紊 提交于 2019-11-28 21:54:36
This is a bit of a puzzle rather than a real-world problem, but I've gotten into a situation where I want to be able to write something that behaves exactly like template<int N> struct SortMyElements { int data[N]; template<typename... TT> SortMyElements(TT... tt) : data{ tt... } { std::sort(data, data+N); } }; int main() { SortMyElements<5> se(1,4,2,5,3); int se_reference[5] = {1,2,3,4,5}; assert(memcmp(se.data, se_reference, sizeof se.data) == 0); } except that I want the SortMyElements constructor to be constexpr . Obviously this is possible for fixed N ; for example, I can specialize

detecting typedef at compile time (template metaprogramming)

≯℡__Kan透↙ 提交于 2019-11-28 20:47:04
I am currently doing some template metaprogramming. In my case I can handle any "iteratable" type, i.e. any type for which a typedef foo const_iterator exists in the same manner. I was trying to use the new C++11 template metaprogramming for this, however I could not find a method to detect if a certain type is missing. Because I also need to turn on/off other template specializations based on other characteristics, I am currently using a template with two parameters, and the second one gets produced via std::enable_if . Here is what I am currently doing: template <typename T, typename Enable

Concatenate compile-time strings in a template at compile time?

不打扰是莪最后的温柔 提交于 2019-11-28 19:57:26
Currently I have: template <typename T> struct typename_struct<T*> { static char const* name() { return (std::string(typename_struct<T>::name()) + "*").c_str(); } }; I wonder if I can avoid the whole bit where I'm forced to allocate a string to perform the concatenation. This is all happening at compile time, i.e. I intend to get the string "int****" when I reference typename_struct<int****>::name() . (Do assume that I have declared a corresponding specialization for int which returns "int" ) As the code is written now, does the compiler do the concatenation with std::string during compile

How to order types at compile-time?

社会主义新天地 提交于 2019-11-28 18:53:33
Consider the following program: #include <tuple> #include <vector> #include <iostream> #include <type_traits> template <class T> struct ordered {}; template <class... T> struct ordered<std::tuple<T...>> { using type = /* a reordered tuple */; }; template <class T> using ordered_t = typename ordered<T>::type; int main(int argc, char* argv[]) { using type1 = std::tuple<char, std::vector<int>, double>; using type2 = std::tuple<std::vector<int>, double, char>; std::cout << std::is_same_v<type1, type2> << "\n"; // 0 std::cout << std::is_same_v<ordered_t<type1>, ordered_t<type2>> << "\n"; // 1

How can I detect if a type can be streamed to an std::ostream?

杀马特。学长 韩版系。学妹 提交于 2019-11-28 17:01:55
I'm trying to write a type trait to detect if a type has overloaded operator<<() suitable to use to an output stream. I'm missing something because I'm always getting true for a simple empty class with no operators at all. Here the code: template<typename S, typename T> class is_streamable { template<typename SS, typename TT> static auto test(SS&& s, TT&& t) -> decltype(std::forward<SS>(s) << std::forward<TT>(t)); struct dummy_t {}; static dummy_t test(...); using return_type = decltype(test(std::declval<S>(), std::declval<T>())); public: static const bool value = !std::is_same<return_type,