C++ 模板和函数解析

标签 c++ templates

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

#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/

相关文章:

javascript - Django 模板存在 javascript 渲染问题

c++ - 当我尝试发出目标代码时,为什么 LLVM 会出现段错误?

javascript - Summernote - 插入带有 Angular Directive(指令)的模板

templates - 在运行时在 Ember 中动态编译 HTMLBars 模板

c++ - 我可以在成员函数上使用 boost::enable_if 吗?

c++ - 使用父模板类的非依赖嵌套类作为子类中的成员

c++ - 如何移动或删除 std::forward_list 中的特定元素?

c# - c#中的AddressOf和c++中的指针有什么区别

c++ - 使用 std::get_time 将时间字符串转换为 std::time_t:错误结果

c++ - 访问数组中对象的成员函数