gpt4 book ai didi

C++ 模板和函数解析

转载 作者:行者123 更新时间:2023-11-27 23:54:23 25 4
gpt4 key购买 nike

这是我在重构一些代码时偶然发现的一个问题,我想知道是否有更好的方法来做到这一点:

#include <iostream>

template<typename T>
class Foo
{
public:
Foo()
{
init(x);
}

T x;
};

void init(int& i)
{
i = 42;
}

int main()
{
Foo<int> foo;
std::cout << foo.x << std::endl;
return 0;
}

不幸的是,这无法通过 GCC 或 Clang 编译。 Foo 的构造函数中调用的函数 init 未声明。在这个玩具示例中,这可以通过将函数本身移到模板之前来解决。但是,在更复杂的上下文中,这可能不起作用。最初,我打算使用 init 的重载来允许对模板中使用的类进行一些设置。

我假设在此上下文中 init 是一个非依赖名称 - 即使函数调用的参数依赖于模板参数(起初对我来说这很奇怪)。有没有办法让它也考虑在模板本身之后定义的函数定义?

我知道我可以使用模板特化(最初是在原始代码中,但我想用更简单的重载替换它):

template<typename>
struct Initializer;

template<>
struct Initializer<int>
{
static void init(int& i)
{
i = 42;
}
}

有没有一种方法可以使它与函数重载一起工作?我知道,boost::serialization 也依赖于自定义类型的函数重载,但我并没有真正找到他们在哪里以及如何实现它。

最佳答案

您可以通过调用模板函数对象来解决排序问题 - 与 boost::hash 查找 ADL 函数 hash_value(x) 的方式相同。

这是可行的,因为模板的扩展被推迟到第一次使用时:

#include <iostream>

namespace A {

struct XX {

friend void init(XX&);
};
}

namespace B {

struct YY {
friend void init(YY&);

};
}

/// default case - call init on T found by ADL
template<class T>
struct call_init
{
void operator()(T& o) const {
init(o);
}
};

template<typename T>
class Foo
{
public:
Foo()
{
auto initialiser = call_init<decltype(this->x)>();
initialiser(this->x);
}

T x;
};

void init(int& x) {
x = 2;
}

// special case, initialise an int
template<> struct call_init<int>
{
void operator()(int& x) const {
init(x);
}
};


int main()
{
Foo<int> foo;
Foo<A::XX> foox;
Foo<B::YY> fooy;
std::cout << foo.x << std::endl;
return 0;
}

关于C++ 模板和函数解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43753724/

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