【问题标题】:Can decltype used to get the type of an argument?decltype 可以用来获取参数的类型吗?
【发布时间】:2014-02-16 18:24:23
【问题描述】:

我试图构建一种(有点)更好的方法来通过使用类型推导从Impossibly Fast Delegate 创建一个委托。但是,我遇到了一些问题。

这是我要简化的功能:

template<typename T, void(T::*TMethod)(E)>
static Delegate<E> create(T * object) { /* ... */ }

当你调用这个函数时,它看起来像这样:

auto del = Delegate<int>::create<A, &A::foo>(&a);

我想要的结果是这样的:

auto del = create_delegate(&a, &A::foo);

我认为 decltype 可以解决问题,但不知何故它不起作用(使用 VS2012):

template<typename E, typename T>
Delegate<E> create_delegate(T * obj, void (T::*method)(E))
{
    return Delegate<E>::create<T, decltype(method)>(obj);
}

我收到错误 C2975:“Delegate::create”:“TMethod”的模板参数无效,预期的编译时常量表达式。

有什么想法吗?

【问题讨论】:

  • 你有必要在运行时决定方法,还是编译时足够好?
  • 您将成员函数的地址作为参数传递给函数create_delegate。作为参数,它不是函数内部的常量。此外,您需要将该地址的 传递给Delegate::create,而不是类型
  • @MartinJ 嗯,我不确定。你的意思是,做类似create_delegate&lt;&amp;A::foo&gt;(&amp;a) 的事情?如果是这样,我认为没问题。
  • @dyp 哦,对。这看起来比我想象的更不可能。
  • @subb AFAIK 没有通用的方法来简化它。一般的问题是,对于template&lt;typename T, T value&gt; integral_constant;,您无法推断类型并从同一表达式(AFAIK)传递值。我知道的唯一方法是使用复制表达式的宏,例如#define MAKE_CONSTANT(EXPR) integral_constant&lt;decltype(EXPR), EXPR&gt;。同样,deduce(&amp;A::foo).value&lt;&amp;A::foo&gt;() 也是可能的,其中deduce 推导出类型,value 将值传递给模板。

标签: c++ templates decltype


【解决方案1】:

为什么不使用 std::function?

#include <functional>
#include <iostream>

struct X {
    void fn(int) {
        std::cout << "Hello\n";
    }
};

template<typename T, typename R, typename A>
std::function<R(A)> create_delegate(T& obj, R (T::*method)(A))
{
    return std::bind(method, &obj, std::placeholders::_1);
}

int main() {
    X x;
    auto delegate = create_delegate(x, &X::fn);
    delegate(1);
}

【讨论】:

  • std::function 的问题是它们没有可比性。这意味着我不能将它们存储在容器中,然后通过搜索容器将它们删除。
  • @subb 您可以通过std::function::target 进行比较,但不可否认,并非在所有情况下都可以。
  • @dyp 很有趣。我会调查的。
猜你喜欢
  • 2018-02-12
  • 2011-06-25
  • 1970-01-01
  • 2015-11-21
  • 1970-01-01
  • 1970-01-01
  • 2021-10-09
  • 1970-01-01
  • 2022-06-26
相关资源
最近更新 更多