1

我试图创建属性向量。这个向量应该是一种“标记”,有助于区分其他元组。

这个简单的代码片段适用于 clang 6.0,不适用于任何 GCC 版本(仅尝试过 7.3.0、8.1.0):

#include <tuple>
#include <string>

using namespace std;

template <class... Ts>
struct vector {
    using tuple_type = std::tuple<Ts...>;

    tuple_type properties;

    template <class... Ps>
    vector(Ps&&... ps)
    : properties(std::forward<Ps>(ps)...)
    {}
};

template <class... Ps> vector(Ps&&... ps) -> vector<Ps...>;

int main() {
    vector v{ std::string("heh"), int(7) };
}

GCC 8.1.0 抛出:

./template_argument_deduction_for_class_templates.cpp: In instantiation of ‘vector<Ts>::vector(Ps&& ...) [with Ps = {std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int}; Ts = {}]’:
./template_argument_deduction_for_class_templates.cpp:22:39:   required from here
./template_argument_deduction_for_class_templates.cpp:15:38: error: no matching function for call to ‘std::tuple<>::tuple(std::__cxx11::basic_string<char>, int)’
  : properties(std::forward<Ps>(ps)...)
                                      ^
In file included from ./template_argument_deduction_for_class_templates.cpp:2:
/usr/include/c++/8.1.0/tuple:901:2: note: candidate: ‘template<class _Alloc> std::tuple<>::tuple(std::allocator_arg_t, const _Alloc&, const std::tuple<>&)’
  tuple(allocator_arg_t, const _Alloc&, const tuple&) { }
  ^~~~~
/usr/include/c++/8.1.0/tuple:901:2: note:   template argument deduction/substitution failed:
./template_argument_deduction_for_class_templates.cpp:15:38: note:   candidate expects 3 arguments, 2 provided
  : properties(std::forward<Ps>(ps)...)
                                      ^
In file included from ./template_argument_deduction_for_class_templates.cpp:2:
/usr/include/c++/8.1.0/tuple:899:2: note: candidate: ‘template<class _Alloc> std::tuple<>::tuple(std::allocator_arg_t, const _Alloc&)’
  tuple(allocator_arg_t, const _Alloc&) { }
  ^~~~~
/usr/include/c++/8.1.0/tuple:899:2: note:   template argument deduction/substitution failed:
./template_argument_deduction_for_class_templates.cpp:15:38: note:   cannot convert ‘std::forward<std::__cxx11::basic_string<char> >((* & ps#0))’ (type ‘std::__cxx11::basic_string<char>’) to type ‘std::allocator_arg_t’
  : properties(std::forward<Ps>(ps)...)
                                      ^
In file included from ./template_argument_deduction_for_class_templates.cpp:2:
/usr/include/c++/8.1.0/tuple:896:7: note: candidate: ‘constexpr std::tuple<>::tuple()’
       tuple() = default;
       ^~~~~
/usr/include/c++/8.1.0/tuple:896:7: note:   candidate expects 0 arguments, 2 provided
/usr/include/c++/8.1.0/tuple:890:11: note: candidate: ‘constexpr std::tuple<>::tuple(const std::tuple<>&)’
     class tuple<>
           ^~~~~~~
/usr/include/c++/8.1.0/tuple:890:11: note:   candidate expects 1 argument, 2 provided
/usr/include/c++/8.1.0/tuple:890:11: note: candidate: ‘constexpr std::tuple<>::tuple(std::tuple<>&&)’
/usr/include/c++/8.1.0/tuple:890:11: note:   candidate expects 1 argument, 2 provided

为什么 GCC 推断 Ts 是空包?我在这里犯了一些错误还是编译器问题?

根据此链接http://en.cppreference.com/w/cpp/compiler_support GCC 应该支持此功能。

4

0 回答 0