gpt4 book ai didi

c++ - 模板类型的重载决策和运算符 << 的问题 - 第 2 部分

转载 作者:太空狗 更新时间:2023-10-29 21:37:36 25 4
gpt4 key购买 nike

给定以下代码:

#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<> 一样

最佳答案

我认为问题出在查找上,我会提供我的理解。

当您调用 operator<<在你的has...结构参数依赖查找开始,自 myType 起与重载的 operator<< 位于同一个命名空间中它成立,你得到一个正确的字符串。但是当你尝试输出 vector它试图搜索重载的 operator<<通过相同的依赖于参数的查找规则并未能执行此操作,因为 std 中没有重载运算符命名空间。因此它会回退到从进行调用的 namespace 开始的非限定搜索,因此它会找到您的 stub operator<<

所以为了修复它,你可能已经放置了 operator<<重载到 std命名空间(标准禁止)或删除您的命名空间——它会产生相同的效果。

不过,您不必将所有内容都放在私有(private)命名空间之外。在全局命名空间中做这样的事情就足够了:

typedef char no;
typedef char yes[2];
template<typename T>
no operator<<(ostream const&, T const&);

或者,如果可能的话,最好要求库用户将他们的重载放入他们的类所在的相同命名空间中。它不适用于 std成员,不过。

关于c++ - 模板类型的重载决策和运算符 << 的问题 - 第 2 部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37139784/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com