gpt4 book ai didi

c++ - 有没有办法让模板根据参数是否为模板类型和值来执行特定的操作?

转载 作者:搜寻专家 更新时间:2023-10-31 02:21:01 26 4
gpt4 key购买 nike

如果传递函数指针或仿函数,我希望辅助函数或模板化结构做不同的事情,但如果我正确理解模板系统,这是不可能的,因为一个是类型,另一个是不是。

我说得对吗?如果可能的话,我希望保持我的 API 不变,将它传递给仿函数或函数指针,但如果不需要,则不会产生存储指针的成本。例如:

template <typename T, void(*fn)(T)>
struct X1
{
T m_t;

X(T t) : m_t(t) {}
void invoke() { fn(m_t); }
};

template <typename T, typename F>
struct X2
{
T m_t;
F m_f;

X(T t, F f) : m_t(t), m_f(f) {}
void invoke() { m_f(m_t); }
};

所以在那种情况下,我要么想让这些结构共享相同的名称,要么让辅助函数使用仿函数或函数指针实例化适当的结构,这些结构放置在相同的参数位置,周围有相同的装饰函数/仿函数。

类似于:

void fn(int) {}
auto functor = [](int){};
int h = 3;

auto x1 = make_X(h, fn);
auto x2 = make_X(h, functor);

make_X() 是我正在寻找的链接。想法?

最佳答案

单一职责原则表明围绕函数指针的优化是无状态的,其余代码应单独处理。

因此,创建一个在代码的一部分中调用 fn 的无状态仿函数:

template<class Sig, Sig* fn>
auto stateless() {
return [](auto&&...args)->decltype(auto){
return fn(decltype(args)(args)...);
};
}

这是 C++14。在 C++11 中,您只需手动编写该 lambda 的等效项。1

空基优化帮助器使得存储类型的空实例便宜且有点容易:

template<class Tag, class T, class=void>
struct ebo {
ebo( T tin ):t(std::forward<T>(tin)) {}
T t;
T& get( Tag ){ return t; }
T const& get( Tag ) const { return t; }
ebo(ebo&&)=default;
ebo(ebo const&)=default;
ebo&operator=(ebo&&)=default;
ebo&operator=(ebo const&)=default;
ebo()=default;
};
template<class Tag, class T>
struct ebo<Tag, T,
std::enable_if_t<std::is_empty<T>{} && !std::is_final<T>{}>
>:
T
{
ebo( T tin ):T(std::forward<T>(tin)) {}
T& get( Tag ){ return *this; }
T const& get( Tag ) const { return *this; }
ebo(ebo&&)=default;
ebo(ebo const&)=default;
ebo&operator=(ebo&&)=default;
ebo&operator=(ebo const&)=default;
ebo()=default;
};

并用上面的代码实现X:

struct F_tag {};
template <typename T, typename F>
struct X:ebo<F_tag, F>
{
X(T tin, F fin):
ebo<F_tag,F>(std::forward<F>(fin)),
m_t(std::forward<T>(tin))
{}

T m_t;
void invoke() { this->get(F_tag{})(m_t); }
};
template<class T, class F>
X<T,F> make_X( T t, F f ) {
return {std::forward<T>(t),std::forward<F>(f)};
}

在使用时,它看起来像:

void fn(int) {}
auto functor = [](int){};
int h = 3;

auto x1 = make_X(h, stateless<void(int),&fn>());
auto x2 = make_X(h, functor);

零字节用于存储 fn(int)functor

我按值(value)考虑:添加转发引用留作练习。


1 stateless 的 C++11 版本:

template<class Sig, Sig* fn>
struct stateless_t {
template<class...Ts>
auto operator()(Ts&&...ts)const
-> decltype( fn(std::declval<Ts>()...) )
{ return fn(std::forward<Ts>(ts)...); }
};
template<class Sig, Sig* fn>
stateless_t<Sig, fn> stateless() { return {}; }

关于c++ - 有没有办法让模板根据参数是否为模板类型和值来执行特定的操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31950872/

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