https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61836
Bug ID: 61836 Summary: Incorrect template argument deduction/substitution failure? Product: gcc Version: 4.9.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ilja.j.honkonen at nasa dot gov Created attachment 33137 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=33137&action=edit Preprocessed source Trying to enable_if a particular implementation of a class member function based on its template argument: template< class Out_T > typename std::enable_if< std::is_same<Out_T, bool>::value, Out_T >::type get_parsed_value(...) template< class Out_T > typename std::enable_if< std::is_same<Out_T, double>::value, Out_T >::type get_parsed_value(...) including std::array and Eigen::Matrix: template<class T> struct is_std_array_double : std::false_type {}; template<size_t N> struct is_std_array_double< std::array<double, N> > : std::true_type {}; template<class T> struct is_eigen_vector_double : std::false_type {}; template<size_t N> struct is_eigen_vector_double< Eigen::Matrix<double, N, 1> > : std::true_type {}; template< class Out_T > typename std::enable_if< detail::is_std_array_double<Out_T>::value, Out_T >::type get_parsed_value(...) template< class Out_T > typename std::enable_if< detail::is_eigen_vector_double<Out_T>::value, Out_T >::type get_parsed_value(...) fails because apparently is_eigen_vector_double returns false for Eigen::Matrix<double, N, 1> even though it shouldn't. The same code compiles with clangs 3.3-5. Compile command: /opt/local/gcc-4.9.1/bin/g++ -I source -std=c++11 -W -Wall -Wextra -pedantic -O3 -I /opt/local/include/eigen3 -I /opt/local/include -L /opt/local/lib -lboost_coroutine-mt -lboost_system-mt -lboost_random-mt -lboost_program_options-mt -I /Users/iljah/include -L /Users/iljah/lib -lmuparserx -I /Users/iljah/include tests/program_options/variable_to_option.cpp -o tests/program_options/variable_to_option.exe -Wno-unused-local-typedefs -save-temps -v Output: Using built-in specs. COLLECT_GCC=/opt/local/gcc-4.9.1/bin/g++ COLLECT_LTO_WRAPPER=/opt/local/gcc-4.9.1/libexec/gcc/x86_64-apple-darwin13.3.0/4.9.1/lto-wrapper Target: x86_64-apple-darwin13.3.0 Configured with: ../gcc-4.9.1/configure --prefix=/opt/local/gcc-4.9.1 --enable-shared --enable-threads=posix --enable-__cxa_atexit --disable-multilib --with-system-zlib --enable-languages=c,c++ --with-gmp=/opt/local --with-mpfr=/opt/local --with-mpc=/opt/local --disable-bootstrap Thread model: posix gcc version 4.9.1 (GCC) COLLECT_GCC_OPTIONS='-mmacosx-version-min=10.9.3' '-I' 'source' '-std=c++11' '-Wall' '-Wextra' '-Wpedantic' '-O3' '-I' '/opt/local/include/eigen3' '-I' '/opt/local/include' '-L/opt/local/lib' '-I' '/Users/iljah/include' '-L/Users/iljah/lib' '-I' '/Users/iljah/include' '-o' 'tests/program_options/variable_to_option.exe' '-Wno-unused-local-typedefs' '-save-temps' '-v' '-shared-libgcc' '-mtune=core2' /opt/local/gcc-4.9.1/libexec/gcc/x86_64-apple-darwin13.3.0/4.9.1/cc1plus -E -quiet -v -I source -I /opt/local/include/eigen3 -I /opt/local/include -I /Users/iljah/include -I /Users/iljah/include -D__DYNAMIC__ tests/program_options/variable_to_option.cpp -fPIC -mmacosx-version-min=10.9.3 -mtune=core2 -std=c++11 -Wall -Wextra -Wpedantic -Wno-unused-local-typedefs -O3 -fpch-preprocess -o variable_to_option.ii ignoring nonexistent directory "/usr/local/include" ignoring nonexistent directory "/opt/local/gcc-4.9.1/lib/gcc/x86_64-apple-darwin13.3.0/4.9.1/../../../../x86_64-apple-darwin13.3.0/include" ignoring duplicate directory "/Users/iljah/include" #include "..." search starts here: #include <...> search starts here: source /opt/local/include/eigen3 /opt/local/include /Users/iljah/include /opt/local/gcc-4.9.1/lib/gcc/x86_64-apple-darwin13.3.0/4.9.1/../../../../include/c++/4.9.1 /opt/local/gcc-4.9.1/lib/gcc/x86_64-apple-darwin13.3.0/4.9.1/../../../../include/c++/4.9.1/x86_64-apple-darwin13.3.0 /opt/local/gcc-4.9.1/lib/gcc/x86_64-apple-darwin13.3.0/4.9.1/../../../../include/c++/4.9.1/backward /opt/local/gcc-4.9.1/lib/gcc/x86_64-apple-darwin13.3.0/4.9.1/include /opt/local/gcc-4.9.1/include /opt/local/gcc-4.9.1/lib/gcc/x86_64-apple-darwin13.3.0/4.9.1/include-fixed /usr/include /System/Library/Frameworks /Library/Frameworks End of search list. COLLECT_GCC_OPTIONS='-mmacosx-version-min=10.9.3' '-I' 'source' '-std=c++11' '-Wall' '-Wextra' '-Wpedantic' '-O3' '-I' '/opt/local/include/eigen3' '-I' '/opt/local/include' '-L/opt/local/lib' '-I' '/Users/iljah/include' '-L/Users/iljah/lib' '-I' '/Users/iljah/include' '-o' 'tests/program_options/variable_to_option.exe' '-Wno-unused-local-typedefs' '-save-temps' '-v' '-shared-libgcc' '-mtune=core2' /opt/local/gcc-4.9.1/libexec/gcc/x86_64-apple-darwin13.3.0/4.9.1/cc1plus -fpreprocessed variable_to_option.ii -fPIC -quiet -dumpbase variable_to_option.cpp -mmacosx-version-min=10.9.3 -mtune=core2 -auxbase variable_to_option -O3 -Wall -Wextra -Wpedantic -Wno-unused-local-typedefs -std=c++11 -version -o variable_to_option.s GNU C++ (GCC) version 4.9.1 (x86_64-apple-darwin13.3.0) compiled by GNU C version 4.8.2, GMP version 6.0.0, MPFR version 3.1.1-p2, MPC version 1.0.2 GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 GNU C++ (GCC) version 4.9.1 (x86_64-apple-darwin13.3.0) compiled by GNU C version 4.8.2, GMP version 6.0.0, MPFR version 3.1.1-p2, MPC version 1.0.2 GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 Compiler executable checksum: bd2008a6eb882424f30fe6b02f71d084 In file included from tests/program_options/variable_to_option.cpp:41:0: source/boundaries/variable_to_option.hpp: In instantiation of ‘typename Last_Variable::data_type pamhd::boundaries::Variable_To_Option<Last_Variable>::get_data(const Last_Variable&, const std::array<double, 3ul>&) [with Last_Variable = Momentum_Density; typename Last_Variable::data_type = Eigen::Matrix<double, 3, 1>]’: tests/program_options/variable_to_option.cpp:135:57: required from here source/boundaries/variable_to_option.hpp:366:13: error: no matching function for call to ‘pamhd::boundaries::Variable_To_Option<Momentum_Density>::get_parsed_value(const std::array<double, 3ul>&)’ >(position); ^ source/boundaries/variable_to_option.hpp:366:13: note: candidates are: source/boundaries/variable_to_option.hpp:408:10: note: template<class Out_T> typename std::enable_if<std::is_same<Out_T, bool>::value, Out_T>::type pamhd::boundaries::Variable_To_Option<Last_Variable>::get_parsed_value(const std::array<double, 3ul>&) [with Out_T = Out_T; Last_Variable = Momentum_Density] >::type get_parsed_value(const std::array<double, 3>& position) ^ source/boundaries/variable_to_option.hpp:408:10: note: template argument deduction/substitution failed: source/boundaries/variable_to_option.hpp: In substitution of ‘template<class Out_T> typename std::enable_if<std::is_same<Out_T, bool>::value, Out_T>::type pamhd::boundaries::Variable_To_Option<Last_Variable>::get_parsed_value(const std::array<double, 3ul>&) [with Out_T = Eigen::Matrix<double, 3, 1>]’: source/boundaries/variable_to_option.hpp:366:13: required from ‘typename Last_Variable::data_type pamhd::boundaries::Variable_To_Option<Last_Variable>::get_data(const Last_Variable&, const std::array<double, 3ul>&) [with Last_Variable = Momentum_Density; typename Last_Variable::data_type = Eigen::Matrix<double, 3, 1>]’ tests/program_options/variable_to_option.cpp:135:57: required from here source/boundaries/variable_to_option.hpp:408:10: error: no type named ‘type’ in ‘struct std::enable_if<false, Eigen::Matrix<double, 3, 1> >’ source/boundaries/variable_to_option.hpp: In instantiation of ‘typename Last_Variable::data_type pamhd::boundaries::Variable_To_Option<Last_Variable>::get_data(const Last_Variable&, const std::array<double, 3ul>&) [with Last_Variable = Momentum_Density; typename Last_Variable::data_type = Eigen::Matrix<double, 3, 1>]’: tests/program_options/variable_to_option.cpp:135:57: required from here source/boundaries/variable_to_option.hpp:430:10: note: template<class Out_T> typename std::enable_if<std::is_same<Out_T, int>::value, Out_T>::type pamhd::boundaries::Variable_To_Option<Last_Variable>::get_parsed_value(const std::array<double, 3ul>&) [with Out_T = Out_T; Last_Variable = Momentum_Density] >::type get_parsed_value(const std::array<double, 3>& position) ^ source/boundaries/variable_to_option.hpp:430:10: note: template argument deduction/substitution failed: source/boundaries/variable_to_option.hpp: In substitution of ‘template<class Out_T> typename std::enable_if<std::is_same<Out_T, int>::value, Out_T>::type pamhd::boundaries::Variable_To_Option<Last_Variable>::get_parsed_value(const std::array<double, 3ul>&) [with Out_T = Eigen::Matrix<double, 3, 1>]’: source/boundaries/variable_to_option.hpp:366:13: required from ‘typename Last_Variable::data_type pamhd::boundaries::Variable_To_Option<Last_Variable>::get_data(const Last_Variable&, const std::array<double, 3ul>&) [with Last_Variable = Momentum_Density; typename Last_Variable::data_type = Eigen::Matrix<double, 3, 1>]’ tests/program_options/variable_to_option.cpp:135:57: required from here source/boundaries/variable_to_option.hpp:430:10: error: no type named ‘type’ in ‘struct std::enable_if<false, Eigen::Matrix<double, 3, 1> >’ source/boundaries/variable_to_option.hpp: In instantiation of ‘typename Last_Variable::data_type pamhd::boundaries::Variable_To_Option<Last_Variable>::get_data(const Last_Variable&, const std::array<double, 3ul>&) [with Last_Variable = Momentum_Density; typename Last_Variable::data_type = Eigen::Matrix<double, 3, 1>]’: tests/program_options/variable_to_option.cpp:135:57: required from here source/boundaries/variable_to_option.hpp:452:10: note: template<class Out_T> typename std::enable_if<std::is_same<Out_T, double>::value, Out_T>::type pamhd::boundaries::Variable_To_Option<Last_Variable>::get_parsed_value(const std::array<double, 3ul>&) [with Out_T = Out_T; Last_Variable = Momentum_Density] >::type get_parsed_value(const std::array<double, 3>& position) ^ source/boundaries/variable_to_option.hpp:452:10: note: template argument deduction/substitution failed: source/boundaries/variable_to_option.hpp: In substitution of ‘template<class Out_T> typename std::enable_if<std::is_same<Out_T, double>::value, Out_T>::type pamhd::boundaries::Variable_To_Option<Last_Variable>::get_parsed_value(const std::array<double, 3ul>&) [with Out_T = Eigen::Matrix<double, 3, 1>]’: source/boundaries/variable_to_option.hpp:366:13: required from ‘typename Last_Variable::data_type pamhd::boundaries::Variable_To_Option<Last_Variable>::get_data(const Last_Variable&, const std::array<double, 3ul>&) [with Last_Variable = Momentum_Density; typename Last_Variable::data_type = Eigen::Matrix<double, 3, 1>]’ tests/program_options/variable_to_option.cpp:135:57: required from here source/boundaries/variable_to_option.hpp:452:10: error: no type named ‘type’ in ‘struct std::enable_if<false, Eigen::Matrix<double, 3, 1> >’ source/boundaries/variable_to_option.hpp: In instantiation of ‘typename Last_Variable::data_type pamhd::boundaries::Variable_To_Option<Last_Variable>::get_data(const Last_Variable&, const std::array<double, 3ul>&) [with Last_Variable = Momentum_Density; typename Last_Variable::data_type = Eigen::Matrix<double, 3, 1>]’: tests/program_options/variable_to_option.cpp:135:57: required from here source/boundaries/variable_to_option.hpp:474:10: note: template<class Out_T> typename std::enable_if<pamhd::boundaries::detail::is_std_array_double<Out_T>::value, Out_T>::type pamhd::boundaries::Variable_To_Option<Last_Variable>::get_parsed_value(const std::array<double, 3ul>&) [with Out_T = Out_T; Last_Variable = Momentum_Density] >::type get_parsed_value(const std::array<double, 3>& position) ^ source/boundaries/variable_to_option.hpp:474:10: note: template argument deduction/substitution failed: source/boundaries/variable_to_option.hpp: In substitution of ‘template<class Out_T> typename std::enable_if<pamhd::boundaries::detail::is_std_array_double<Out_T>::value, Out_T>::type pamhd::boundaries::Variable_To_Option<Last_Variable>::get_parsed_value(const std::array<double, 3ul>&) [with Out_T = Eigen::Matrix<double, 3, 1>]’: source/boundaries/variable_to_option.hpp:366:13: required from ‘typename Last_Variable::data_type pamhd::boundaries::Variable_To_Option<Last_Variable>::get_data(const Last_Variable&, const std::array<double, 3ul>&) [with Last_Variable = Momentum_Density; typename Last_Variable::data_type = Eigen::Matrix<double, 3, 1>]’ tests/program_options/variable_to_option.cpp:135:57: required from here source/boundaries/variable_to_option.hpp:474:10: error: no type named ‘type’ in ‘struct std::enable_if<false, Eigen::Matrix<double, 3, 1> >’ source/boundaries/variable_to_option.hpp: In instantiation of ‘typename Last_Variable::data_type pamhd::boundaries::Variable_To_Option<Last_Variable>::get_data(const Last_Variable&, const std::array<double, 3ul>&) [with Last_Variable = Momentum_Density; typename Last_Variable::data_type = Eigen::Matrix<double, 3, 1>]’: tests/program_options/variable_to_option.cpp:135:57: required from here source/boundaries/variable_to_option.hpp:529:10: note: template<class Out_T> typename std::enable_if<pamhd::boundaries::detail::is_eigen_vector_double<Out_T>::value, Out_T>::type pamhd::boundaries::Variable_To_Option<Last_Variable>::get_parsed_value(const std::array<double, 3ul>&) [with Out_T = Out_T; Last_Variable = Momentum_Density] >::type get_parsed_value(const std::array<double, 3>& position) ^ source/boundaries/variable_to_option.hpp:529:10: note: template argument deduction/substitution failed: source/boundaries/variable_to_option.hpp: In substitution of ‘template<class Out_T> typename std::enable_if<pamhd::boundaries::detail::is_eigen_vector_double<Out_T>::value, Out_T>::type pamhd::boundaries::Variable_To_Option<Last_Variable>::get_parsed_value(const std::array<double, 3ul>&) [with Out_T = Eigen::Matrix<double, 3, 1>]’: source/boundaries/variable_to_option.hpp:366:13: required from ‘typename Last_Variable::data_type pamhd::boundaries::Variable_To_Option<Last_Variable>::get_data(const Last_Variable&, const std::array<double, 3ul>&) [with Last_Variable = Momentum_Density; typename Last_Variable::data_type = Eigen::Matrix<double, 3, 1>]’ tests/program_options/variable_to_option.cpp:135:57: required from here source/boundaries/variable_to_option.hpp:529:10: error: no type named ‘type’ in ‘struct std::enable_if<false, Eigen::Matrix<double, 3, 1> >’ source/boundaries/variable_to_option.hpp: In member function ‘typename Last_Variable::data_type pamhd::boundaries::Variable_To_Option<Last_Variable>::get_data(const Last_Variable&, const std::array<double, 3ul>&) [with Last_Variable = Momentum_Density; typename Last_Variable::data_type = Eigen::Matrix<double, 3, 1>]’: source/boundaries/variable_to_option.hpp:367:2: warning: control reaches end of non-void function [-Wreturn-type] } ^