Clang does not compile my code, but g ++ does

Can someone help me with this code:

#include <type_traits> #include <vector> struct nonsense { }; template <struct nonsense const* ptr, typename R> typename std::enable_if<!std::is_void<R>::value, int>::type fo(void* const) { return 0; } template <struct nonsense const* ptr, typename R> typename std::enable_if<std::is_void<R>::value, int>::type fo(void* const) { return 1; } typedef int (*func_type)(void*); template <std::size_t O> void run_me() { static struct nonsense data; typedef std::pair<char const* const, func_type> pair_type; std::vector<pair_type> v; v.push_back(pair_type{ "a", fo<&data, int> }); v.push_back(pair_type{ "b", fo<&data, void> }); } int main(int, char*[]) { run_me<2>(); return 0; } 

clang-3.3 does not compile this code, but g ++ - 4.8.1 does, which of the two compilers is right? Is something wrong with the code, as I suspect?

Error:

 a.cpp:32:15: error: no matching constructor for initialization of 'pair_type' (aka 'pair<const char *const, func_type>') v.push_back(pair_type{ "a", fo<&data, int> }); ^ ~~~~~~~~~~~~~~~~~~~~~~~ a.cpp:33:15: error: no matching constructor for initialization of 'pair_type' (aka 'pair<const char *const, func_type>') v.push_back(pair_type{ "b", fo<&data, void> }); ^ ~~~~~~~~~~~~~~~~~~~~~~~~ 
+3
source share
1 answer

Moving static struct nonsense data outside a function gets the code to compile. I'm not smart enough to tell you why.

To configure data for different values โ€‹โ€‹of the O parameter, you can define nonsense as follows:

 template <size_t> struct nonsense { static nonsense data; โ‹ฎ }; 

... and use it that way ...

 template <std::size_t O, typename R> typename std::enable_if<!std::is_void<R>::value, int>::type fo(void* const) { // Use nonsense<O>::data } template <std::size_t O, typename R> typename std::enable_if<std::is_void<R>::value, int>::type fo(void* const) { // Use nonsense<O>::data } โ‹ฎ template <std::size_t O> void run_me() { std::vector<std::pair<char const* const, func_type>> v; v.emplace_back("a", fo<O, int >); v.emplace_back("b", fo<O, void>); } 
+1
source

Source: https://habr.com/ru/post/948283/


All Articles