gpt4 book ai didi

c++ - SFINAE 用于泛型类型的泛型操作

转载 作者:太空狗 更新时间:2023-10-29 20:02:06 26 4
gpt4 key购买 nike

我有

  • Value 类,可以用不同类型(Foo、Bar、int、...)构造。

  • class Value 应该有常见的操作,如 <<、==、<、... 在基础类型上进行

  • 我在类定义之外添加了运算符 <<

我需要以下代码:

#include <iostream>

struct Foo {
};

struct Bar {
};

struct Value {
template<typename T>
Value(T) {
}
};

std::ostream &operator<<(std::ostream &os, const Bar &) {
return os << "Bar\n";
}

std::ostream &operator<<(std::ostream &os, const Value &value) {

auto visitor = [&](auto a) -> decltype(os << a) {
return os << a;
};

// Works
visitor(Bar{});

// Infinity call of this function with Value.
visitor(Foo{});

return os;
}

int main() {
std::cout << Value(1);

return 0;
}

Live example.

问题:如果底层类型没有实现运算符<<,Value 中的运算符<< 会被称为递归无限。我想得到一个编译器错误,例如 no match for call operator<<(std:ostream&, const Value&)... 以将 SFINAE 与我的访问者模式一起使用(此处未显示)。

我需要的是这样的:

[&](auto a) -> std::enable_if_t<addressof?(os << a) != addressof?(os << Value{})>::value> {
return os << a;
};

如果功能相同,则禁用此 lambda。这可能吗?

没有值(value)的解决方案:

  • 明确值(value)
  • 禁止使用 Foo 构建 Value

最佳答案

你可以添加一个包装器来强制只进行一次转换:

template <typename T>
struct OneConversion
{
OneConversion(const T& t) : t(t) {}

operator const T&() const {return t;}

const T& t;
};

template <typename T>
struct isOneConversion : std::false_type {};

template <typename T>
struct isOneConversion<OneConversion<T>> : std::true_type {};

struct Value {
template<typename T, std::enable_if_t<!isOneConversion<T>::value>* = nullptr>
Value(T) {}
};

std::ostream &operator<<(std::ostream &os, const Value &value) {

auto visitor = [&](auto a) -> decltype(os << OneConversion<decltype(a)>(a)) {
return os << OneConversion<decltype(a)>(a);
};

// Works
visitor(Bar{});

visitor(Foo{}); // Error as expected.

return os;
}

Demo

关于c++ - SFINAE 用于泛型类型的泛型操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46772840/

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