print
对于特定类型的上下文(第一个参数)
超负荷也是朋友,没有向前声明这些上下文
clause.h
#include <iostream>
template <typename T> struct clause;
template <typename Context, typename T>
void print(const Context &, const clause<T> &c) {
std::cerr << c.i << " friend\n";
}
// In this simplified code, T is not used, but would normally be.
template <typename T> struct clause {
private:
template <typename Context, typename U>
friend void print(const Context &, const clause<U> &c);
int i = 8;
};
#include "clause.h"
class special_context {};
template <typename T> void print(const special_context &, const clause<T> &c) {
std::cerr << c.i << " overload\n";
}
int main() {
clause<int> c;
print(nullptr, c);
// print(special_context{}, c); // Fails as the overload is not a friend.
}
我还尝试在班级主体中定义“通用”版本:
// Alternative for clause.h
template <typename T> struct clause {
template <typename Context>
friend void print(const Context &, const clause &c) {
std::cerr << c.i << " friend\n";
}
private:
int i = 8;
};
但现在也失败了,因为现在的过载分辨率对
special_context
。
超负荷也是朋友,
我们做不到。我们必须将超载功能列为朋友。#include <functional>
#include <iostream>
#include <type_traits>
template <typename T>
struct clause {
private:
friend struct print;
int i = 8;
};
class special_context {};
struct print {
template <typename Context, typename T>
void operator()(const Context&, const clause<T>& c) {
std::cerr << c.i << " friend\n";
}
template <typename T>
void operator()(const special_context&, const clause<T>& c) {
std::cerr << c.i << " overload\n";
}
};
int main() {
clause<int> c;
std::invoke(print{}, nullptr, c);
std::invoke(print{}, special_context{}, c);
}
https://godbolt.org/z/5qznpt3or