【发布时间】:2016-05-10 13:19:37
【问题描述】:
给定以下代码:
#include <string>
#include <type_traits>
#include <sstream>
#include <vector>
#include <iostream>
using namespace std;
namespace has_insertion_operator_impl {
typedef char no;
typedef char yes[2];
struct any_t {
template <typename T>
any_t(T const&);
};
no operator<<(ostream const&, any_t const&);
yes& test(ostream&);
no test(no);
template <typename T>
struct has_insertion_operator {
static ostream& s;
static T const& t;
static bool const value = sizeof(test(s << t)) == sizeof(yes);
};
}
template <typename T>
struct has_insertion_operator : has_insertion_operator_impl::has_insertion_operator<T> {};
template <class T>
typename enable_if<has_insertion_operator<T>::value, string>::type stringify(const T& in) {
stringstream stream;
stream << in;
return stream.str();
}
template <class T>
typename enable_if< ! has_insertion_operator<T>::value, string>::type stringify(const T&) {
return "{?}";
}
// ======= OVERLOADS PROVIDED BY THE USER =======
template<typename T, typename T2>
struct myType { T data; T2 op; };
template<typename T, typename T2>
ostream& operator<<(ostream& s, const myType<T, T2>&) { s << "myType"; return s; }
template<typename T>
ostream& operator<<(ostream& s, const vector<T>&) { s << "vector<T>"; return s; }
template<typename T, typename A>
ostream& operator<<(ostream& s, const vector<T, A>&) { s << "vector<T, A>"; return s; }
int main() {
myType<int, float> a; cout << stringify(a) << endl; // prints "myType"
cout << stringify(6) << endl; // prints "6"
vector<int> v(5); cout << stringify(v) << endl; // prints "{?}"
return 0;
}
为什么模板 myType<> 被字符串化,而模板化的 vector<> 类型却没有?
对于vector<> 类型,我得到默认的{?} 字符串化,但我显然希望调用底部的重载之一——就像myType<> 一样
编辑:
这里的实际问题是为什么has_insertion_operator<vector<int>> 是假的?
我在 C++98 中也需要这个
operator<< 重载应该在 stringify() 之后提供 - 就像 myType<> 一样
【问题讨论】:
-
很明显为什么向量没有被字符串化。问题可以简化为“为什么
has_insertion_operator<vector<int>>是假的?” -
@user2079303:它有什么“明显”的地方?那里有一个
ostream& operator<<(ostream& s, const vector<T>&)。 -
@LightnessRacesinOrbit 实际上他是对的——这是特性的错——它驱动了
enable_if<>和 SFINAE -
@onqtam:没有什么“显而易见”的。我认为 user2079303 没有意识到 OP 已经尝试创建自己的
operator<<来匹配。 -
@LightnessRacesinOrbit 显然没有使用重载,因为它被
enable_if<has_insertion_operator<T>::value, string>::type禁用。不明显的是为什么has_insertion_operator<T>::value是假的,尽管ostream& operator<<(ostream& s, const vector<T>&)。因此,我建议简化问题。
标签: c++ templates operator-overloading overload-resolution