我试图创建属性向量。这个向量应该是一种“标记”,有助于区分其他元组。
这个简单的代码片段适用于 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 应该支持此功能。