C++14 模板偏特化不可见
C++14 template partial specialization not visible
我想了解为什么模板偏特化变得不可见。
我正在做一个小例子来说明我是如何遇到下面的错误的。
该示例尝试重载 operator<<
以打印到 ostream。
在问题 1 中有一个解决方案可以打印元组。我的问题是关于为什么下面的那个因不可见错误而失败。
来自 clang 的完整错误:
call to function 'operator<<' that is neither visible in the template definition nor found by argument-dependent
lookup
operator<<(os, std::get<0>(t));
^
testing.cpp:9:47: note: in instantiation of member function 'tuple_printer<1, std::__1::tuple<std::__1::tuple<const char *, int> > >::print'
requested here
tuple_printer<s-1, std::tuple<T...>>::print(os, t);
^
testing.cpp:33:52: note: in instantiation of member function 'tuple_printer<2, std::__1::tuple<const char *, int> >::print' requested here
tuple_printer<sizeof...(T), std::tuple<T...>>::print(os, t);
^
testing.cpp:40:15: note: in instantiation of function template specialization 'operator<<<const char *, int>' requested here
std::cout << std::make_tuple("hello", 5) << std::endl;
^
testing.cpp:30:15: note: 'operator<<' should be declared prior to the call site
std::ostream& operator<<(std::ostream& os, const std::tuple<T...>& t)
示例代码:
#include <tuple>
#include <iostream>
template<size_t s, typename... T>
struct tuple_printer{
static void print(std::ostream& os, const std::tuple<T...>& t){
os << ", ";
os << std::get<s-1>(t);
tuple_printer<s-1, std::tuple<T...>>::print(os, t);
}
};
template<typename... T>
struct tuple_printer<0, T...>{
static void print(std::ostream& os, const std::tuple<T...>& t){
//nothing to do here
}
};
template<typename... T>
struct tuple_printer<1, T...>{
static void print(std::ostream& os, const std::tuple<T...>& t){
//no need for comma separator
os << std::get<0>(t);
}
};
template <typename... T>
std::ostream& operator<<(std::ostream& os, const std::tuple<T...>& t)
{
os << "[";
tuple_printer<sizeof...(T), std::tuple<T...>>::print(os, t);
return os << "]";
}
int main()
{
std::cout << std::make_tuple(2, 3.14159F, 2345.678) << std::endl;
std::cout << std::make_tuple("hello", 5) << std::endl;
std::cout << std::make_tuple() << std::endl;
return 0;
}
std::cout << std::make_tuple(2, 3.14159F, 2345.678)
这调用std::ostream& operator<< <int, float, double>(std::ostream& os, const std::tuple<int, float, double>& t)
从内部调用 tuple_printer<sizeof...(T), std::tuple<T...>>::print(os, t);
是
void tuple_printer<3, std::tuple<int, float, double>>::print(
std::ostream& os,
const std::tuple<std::tuple<int, float, double>>& t);
注意加倍的 tuple
。您显式地将 tuple
作为单个参数传递给 T...
,然后该函数将其包装在另一个元组中。
在这个 print
函数中,您调用
std::get<2>(t)
编译失败,因为 t
只有一个元素。
在其他情况下,get<s-1>(t)
成功,但 returns 是一个元组,而不是基本元素,因此您尝试将其传递给 operator<<
,但 operator<<
对于元组尚未声明。
1. tuple_printer
不带 size_t, tuple<T...>
但 size_t, T...
:
将tuple_printer<s-1, std::tuple<T...>>
替换为:
tuple_printer<s-1, T...>
和tuple_printer<sizeof...(T), std::tuple<T...>>
与:
tuple_printer<sizeof...(T), T...>
2. 此外,我猜您希望基本模板中的语句顺序略有不同:
tuple_printer<s-1, T...>::print(os, t);
os << ", ";
os << std::get<s-1>(t);
我想了解为什么模板偏特化变得不可见。
我正在做一个小例子来说明我是如何遇到下面的错误的。
该示例尝试重载 operator<<
以打印到 ostream。
在问题 1 中有一个解决方案可以打印元组。我的问题是关于为什么下面的那个因不可见错误而失败。
来自 clang 的完整错误:
call to function 'operator<<' that is neither visible in the template definition nor found by argument-dependent
lookup
operator<<(os, std::get<0>(t));
^
testing.cpp:9:47: note: in instantiation of member function 'tuple_printer<1, std::__1::tuple<std::__1::tuple<const char *, int> > >::print'
requested here
tuple_printer<s-1, std::tuple<T...>>::print(os, t);
^
testing.cpp:33:52: note: in instantiation of member function 'tuple_printer<2, std::__1::tuple<const char *, int> >::print' requested here
tuple_printer<sizeof...(T), std::tuple<T...>>::print(os, t);
^
testing.cpp:40:15: note: in instantiation of function template specialization 'operator<<<const char *, int>' requested here
std::cout << std::make_tuple("hello", 5) << std::endl;
^
testing.cpp:30:15: note: 'operator<<' should be declared prior to the call site
std::ostream& operator<<(std::ostream& os, const std::tuple<T...>& t)
示例代码:
#include <tuple>
#include <iostream>
template<size_t s, typename... T>
struct tuple_printer{
static void print(std::ostream& os, const std::tuple<T...>& t){
os << ", ";
os << std::get<s-1>(t);
tuple_printer<s-1, std::tuple<T...>>::print(os, t);
}
};
template<typename... T>
struct tuple_printer<0, T...>{
static void print(std::ostream& os, const std::tuple<T...>& t){
//nothing to do here
}
};
template<typename... T>
struct tuple_printer<1, T...>{
static void print(std::ostream& os, const std::tuple<T...>& t){
//no need for comma separator
os << std::get<0>(t);
}
};
template <typename... T>
std::ostream& operator<<(std::ostream& os, const std::tuple<T...>& t)
{
os << "[";
tuple_printer<sizeof...(T), std::tuple<T...>>::print(os, t);
return os << "]";
}
int main()
{
std::cout << std::make_tuple(2, 3.14159F, 2345.678) << std::endl;
std::cout << std::make_tuple("hello", 5) << std::endl;
std::cout << std::make_tuple() << std::endl;
return 0;
}
std::cout << std::make_tuple(2, 3.14159F, 2345.678)
这调用std::ostream& operator<< <int, float, double>(std::ostream& os, const std::tuple<int, float, double>& t)
从内部调用 tuple_printer<sizeof...(T), std::tuple<T...>>::print(os, t);
是
void tuple_printer<3, std::tuple<int, float, double>>::print(
std::ostream& os,
const std::tuple<std::tuple<int, float, double>>& t);
注意加倍的 tuple
。您显式地将 tuple
作为单个参数传递给 T...
,然后该函数将其包装在另一个元组中。
在这个 print
函数中,您调用
std::get<2>(t)
编译失败,因为 t
只有一个元素。
在其他情况下,get<s-1>(t)
成功,但 returns 是一个元组,而不是基本元素,因此您尝试将其传递给 operator<<
,但 operator<<
对于元组尚未声明。
1. tuple_printer
不带 size_t, tuple<T...>
但 size_t, T...
:
将tuple_printer<s-1, std::tuple<T...>>
替换为:
tuple_printer<s-1, T...>
和tuple_printer<sizeof...(T), std::tuple<T...>>
与:
tuple_printer<sizeof...(T), T...>
2. 此外,我猜您希望基本模板中的语句顺序略有不同:
tuple_printer<s-1, T...>::print(os, t);
os << ", ";
os << std::get<s-1>(t);