For some magic with sfinae I have the header below in my software package. When moving from x86_64-slc6-gcc49-opt to x86_64-centos7-gcc62-opt, the build fails (in dictionary generation with genreflex) with
Info in <TUnixSystem::ACLiC>: creating shared library /somelongpath/./c++14_compat_h.so
In file included from input_line_12:9:
/somelongpath/./c++14_compat.h:52:36: error:
type alias template redefinition with different types ('typename make_void<Ts...>::type' vs 'void')
template<typename... Ts> using void_t = typename make_void<Ts...>::type;
^
/cvmfs/sft.cern.ch/lcg/contrib/gcc/6.2.0native/x86_64-centos7/bin/../lib/gcc/x86_64-pc-linux-gnu/6.2.0/../../../../include/c++/6.2.0/type_traits:2536:31: note:
previous definition is here
template<typename...> using void_t = void;
^
Error in <ACLiC>: Dictionary generation failed!
Trying to make the error easier to reproduce (and understand where it comes from) I arrived at the following reproducer:
SHELL > # do something to set up root
SHELL > root -n -b
root [0] .L c++14_compat.h++
And tried this using the root installations on /afs/cern.ch/sw/lcg/app/releases/ROOT/, /cvmfs/sft.cern.ch/lcg/views/LCG_88, /cvmfs/sft.cern.ch/lcg/views/dev, and trying gcc49 vs 62, and trying a centos7 machine and lxplus(slc6), i believe this is a regression when going from the gcc 4.9 builds to gcc 6.2.
Comments / thoughts?
header for reproduction:
/** @file c++14_compat.h
*
* @brief some required constructs from C++ 14 implemented using C++ 11
*/
#ifndef CPP14_COMPAT_H
#define CPP14_COMPAT_H
#if __cplusplus > 201103L // well, g++ and icpc have strange values here in c++14 mode
// C++14 - use the standard's facilities
#include <utility>
#elif __cplusplus >= 201103L
// C++11 - implement what's needed
// C++14 Compile-time integer sequences -- this can go once we use C++14...
namespace std {
template<size_t... indexes>
struct index_sequence {
static constexpr size_t size() { return sizeof...(indexes); }
};
template<size_t currentIndex, size_t... indexes>
struct make_index_sequence_helper;
template<size_t...indexes>
struct make_index_sequence_helper<0, indexes...> {
typedef index_sequence<indexes...> type;
};
template<size_t currentIndex, size_t... indexes>
struct make_index_sequence_helper {
typedef typename make_index_sequence_helper<currentIndex - 1,
currentIndex - 1, indexes...>::type type;
};
template<size_t N>
struct make_index_sequence : public make_index_sequence_helper<N>::type
{ };
}
#else // __cplusplus
// not even C++11 support
#error "Your C++ compiler must support at least C++11."
#endif // __cplusplus
// FIXME: what is the defined value of compliant C++17 compilers?
#if __cplusplus > 201402L
#include <type_traits>
#else
namespace std {
/// little helper for the SFINAE idiom we'll use (not required in C++17)
template<typename... Ts> struct make_void { typedef void type;};
/// little helper for the SFINAE idiom we'll use (not required in C++17)
template<typename... Ts> using void_t = typename make_void<Ts...>::type;
}
#endif // __cplusplus
#endif // CPP14_COMPAT_H