C ++模板代码生成错误:在扣除“自动”之前使用“ some_variable”

时间:2019-05-08 01:55:06

标签: c++17 variadic-templates template-meta-programming auto generic-lambda

我在使用此特定代码时遇到了一些问题。问题很可能与存储在 tuple 中的类型为Harry 的成员的指针和带有{的 vector {1}} type变量,因为所有其他更简单的变体都可以使用。

我用g ++遇到的错误:


Harry

代码:

main.cpp: In instantiation of 'abra(const std::vector<A>&, const std::tuple<_Elements ...>&) [with A = Harry; B = {int Harry::*, int* Harry::*}]::<lambda(const auto:1&)> [with auto:1 = int Harry::*]':

main.cpp:10:13:   required from 'void tuple_foreach_constexpr(const std::tuple<T ...>&, F) [with long unsigned int i = 0; long unsigned int size = 2; F = abra(const std::vector<A>&, const std::tuple<_Elements ...>&) [with A = Harry; B = {int Harry::*, int* Harry::*}]::<lambda(const auto:1&)>; T = {int Harry::*, int* Harry::*}]'

main.cpp:17:82:   required from 'void tuple_foreach_constexpr(const std::tuple<_Elements ...>&, F) [with F = abra(const std::vector<A>&, const std::tuple<_Elements ...>&) [with A = Harry; B = {int Harry::*, int* Harry::*}]::<lambda(const auto:1&)>; T = {int Harry::*, int* Harry::*}]'

main.cpp:29:32:   required from 'void abra(const std::vector<A>&, const std::tuple<_Elements ...>&) [with A = Harry; B = {int Harry::*, int* Harry::*}]'

main.cpp:56:27:   required from here

main.cpp:31:82: error: use of 'a' before deduction of 'auto'

             if constexpr(std::is_pointer<typename std::remove_reference<decltype(a.*x)>::type>::value)

                                                                                  ^

main.cpp:33:30: error: invalid type argument of unary '*' (have 'int')

                 std::cout << *(a.*x) << std::endl;

                              ^~~~~~~

main.cpp:6:6: error: 'void tuple_foreach_constexpr(const std::tuple<T ...>&, F) [with long unsigned int i = 1; long unsigned int size = 2; F = abra(const std::vector<A>&, const std::tuple<_Elements ...>&) [with A = Harry; B = {int Harry::*, int* Harry::*}]::<lambda(const auto:1&)>; T = {int Harry::*, int* Harry::*}]', declared using local type 'abra(const std::vector<A>&, const std::tuple<_Elements ...>&) [with A = Harry; B = {int Harry::*, int* Harry::*}]::<lambda(const auto:1&)>', is used but never defined [-fpermissive]

 void tuple_foreach_constexpr(const std::tuple<T...>& tuple, F func)

      ^~~~~~~~~~~~~~~~~~~~~~~

如果有人对如何解决此问题有一些提示,那就太好了。

(我知道这一切似乎都变得毫无意义,为什么任何人都需要这样做。但是,我的首要任务不是编写好的,可用的代码,而是学习知识,我也很想得到这种架构我当时想工作。)

1 个答案:

答案 0 :(得分:2)

  

如果有人对如何解决此问题有一些提示,那就太好了。

首先:我用g ++重现了您的错误,但是我的clang ++(7.0.1)可以毫无问题地编译您的代码。

谁是对的? g ++还是clang ++?

我不是语言律师,也不确定,但是我怀疑这是g ++错误。

在说什么g ++?

是说在这个循环中

for(const auto& a : a_vector)
{
    tuple_foreach_constexpr(b_tuple, [&a](const auto &x)
    {
        if constexpr(std::is_pointer<typename std::remove_reference<decltype(a.*x)>::type>::value)
        {
            std::cout << *(a.*x) << std::endl;
        }
        else
        {
            std::cout << a.*x << std::endl;
        } // this does NOT work

        //std::cout << a.*x << std::endl; // this does work
    });
}

a变量,即auto变量(const auto& a : a_vector),因此必须使用在lambda函数内部捕获的编译器推导它的类型({{ 1}}),然后再减去类型。

无论如何,问题的解决方法很简单:使g ++满意,明确定义。

您知道decltype(a.*x)a的元素,它被定义为a_vector,因此您知道std::vector<A> const &a

所以,如果您编写循环

A const &

不再需要推断for ( A const & a : a_vector ) { // .... } 的类型,您的代码也可以使用g ++进行编译。