gpt4 book ai didi

c++ - C++:递归成员函数模板

转载 作者:行者123 更新时间:2023-12-02 10:22:40 25 4
gpt4 key购买 nike

我想使用c++ 14编写通用对象打印机。这个想法是在任意包装的对象中搜索toString()方法。在此示例中,它仅理解指针间接获取可打印对象。

以下代码在clang-8上编译,但在gcc-9上失败:

#include <iostream>
#include <memory>
#include <string>

#include <boost/optional.hpp>

struct A {
std::string toString() const { return "gotchA"; }
};

struct Printer {
void print(const std::string &s) { std::cout << s << std::endl; }

template <typename T>
auto print(const T &o) -> std::enable_if_t<
std::is_same<decltype(o.toString()), std::string>::value> {
print(o.toString());
}

template <typename T> auto print(const T &o) -> decltype(this->print(*o));
};

template <typename T>
auto Printer::print(const T &o) -> decltype(this->print(*o)) {
print(*o);
}

int main() {
Printer{}.print(A{});
Printer{}.print(boost::make_optional(std::make_unique<A>()));
}

gcc给出以下错误:
g++ -std=c++14 recursive.cpp
recursive.cpp:24:6: error: no declaration matches ‘decltype (((Printer*)this)->Printer::print((* o))) Printer::print(const T&)’
24 | auto Printer::print(const T &o) -> decltype(this->print(*o)) {
| ^~~~~~~
recursive.cpp:20:30: note: candidates are: ‘template<class T> decltype (((Printer*)this)->Printer::print((* o))) Printer::print(const T&)’
20 | template <typename T> auto print(const T &o) -> decltype(this->print(*o));
| ^~~~~
recursive.cpp:15:8: note: ‘template<class T> std::enable_if_t<std::is_same<decltype (o.toString()), std::__cxx11::basic_string<char> >::value> Printer::print(const T&)’
15 | auto print(const T &o) -> std::enable_if_t<
| ^~~~~
recursive.cpp:12:8: note: ‘void Printer::print(const string&)’
12 | void print(const std::string &s) { std::cout << s << std::endl; }
| ^~~~~
recursive.cpp:11:8: note: ‘struct Printer’ defined here
11 | struct Printer {
| ^~~~~~~

正如我在这些编译器输出行中所看到的,候选对象与外部定义签名没有区别(除了开头的 template;添加了空格):
recursive.cpp:24:6: error: no declaration matches            ‘decltype (((Printer*)this)->Printer::print((* o))) Printer::print(const T&)’
recursive.cpp:20:30: note: candidates are: ‘template<class T> decltype (((Printer*)this)->Printer::print((* o))) Printer::print(const T&)’

我如何实现递归?我究竟做错了什么?

谢谢!

最佳答案

函数名称不在其自己的声明程序的范围内,包括任何尾随返回类型。结果,重新声明的解释与原始声明的解释不同,因为随后可以使用原始声明。 relevant rule并不清楚如何处理这种情况:特别地,名称print在技术上并不是“从属名称”(仅作为名称进行比较),因为它是类成员访问的一部分。 (如果是,则递归无论如何都不会起作用,因为仅使用了第一个声明中的查找。)

这里的常用方法是使用具有部分特化的类:

template<class> struct Printer;

template<class T>
void print(const T &t) {Printer<T>::go(t);}

template<class T,class=void>
struct Printer { // recursive case
void go(const T &t) {print(*t);}
};

template<>
struct Printer<std::string,void> {
void go(const std::string &s) { std::cout << s << std::endl; }
};

template<class T>
struct Printer<T,std::enable_if_t<
std::is_same<decltype(std::declval<T&>().toString()),
std::string>::value>> {
void go(const T &t) {print(t.toString());}
};

最后一个条件可能仅以 toString的存在为条件更好,以便它可以利用递归支持。

关于c++ - C++:递归成员函数模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59435419/

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