【问题标题】:Forwarding the decltype detection - C++ 11转发 decltype 检测 - C++ 11
【发布时间】:2012-12-18 02:51:42
【问题描述】:

我想使用decltype 将方法的返回类型虚拟绑定到类似的变量类型

#include <iostream>

decltype(a) foo()                     // my point
{
  return 4.3f;
}

int main(int argc, char* argv[])
{
  auto a = 5.5f;
  std::cout << foo() << std::endl;
  return(0);
}

但您可以轻松猜到,此代码在 Linux 上的 g++-4.7.2 下无法编译。

有解决方法吗?我知道auto,但这不是我想要使用的(我不想使用auto 作为foo() 的返回类型)。

【问题讨论】:

  • 虚拟地绑定返回类型”是什么意思?是指 virtualvirtual functions 一样吗? IE。您是在谈论某种运行时(后期)绑定吗?
  • @jogojapan "virtual" as "normal people" 认为,我的意思是foo 应该表达与a 相同的返回类型
  • 要将a 的类型和foo 的返回类型绑定在一起,为两者引入类型同义词不是很有意义吗?

标签: c++ c++11 g++ decltype


【解决方案1】:

你可以使用模板

template <typename T>
T foo()
{
    return 4.3f;
}

并使用foo&lt;float&gt;() 调用它

如果在函数之前声明了a,您也可以使用decltype,如下所示:

auto a = 5.3f;

decltype(a) foo()
{
   return 4.3f;  
}

【讨论】:

  • 对于基于模板的解决方案:您实际上可以说foo&lt;decltype(a)&gt;() 而不是foo&lt;float&gt;()
【解决方案2】:

您的目标到底是什么?可以将变量传递给函数吗?如果不是,该函数如何知道要使用什么类型?如果您可以将变量传递给函数,则可以使用模板:

template<typename T>
T foo(T) {
    return 4.3f;
}

现在你可以这样称呼它

std::cout << foo(a) << std::endl;

这里的变量只是用来获取它的类型。如果不想传入变量,则需要直接提供类型,例如

template<typename T>
T foo() {
     return 4.3f;
}

std::cout << foo<decltype(a)>() << std::endl;

但这当然很丑。

现在,如果您愿意使用宏,您可以稍微简化一下:

template<typename T>
T _foo() {
    return 4.3f;
}
#define foo() _foo<decltype(a)>()

std::cout << foo() << endl;

当然,这会硬编码调用 foo() 时必须在范围内的变量的名称。


这里的根本问题是函数不能隐式使用变量的类型,因为函数是先声明的。因此,如果模板不是一个好的解决方案,那么唯一的选择就是在函数和变量都可以访问它的地方声明类型。这可以通过typedef 来完成:

typedef float atype;

atype foo() {
    return 4.3f;
}

int main() {
    atype a = 5.5f;
    std::cout << foo() << std::endl;
}

或者,您可以简单地决定 foo() 的返回值被认为是相关类型的权威:

float foo() {
    return 4.3f;
}

int main() {
    decltype(foo()) a = 5.5f;
    std::cout << foo() << std::endl;
}

【讨论】:

  • 我的观点只是在声明用作参数的变量之前使用 decltype。我不是要求坚持 ISO 标准,我在想也许某些编译器可以通过一些 hack 支持转发的 decltype。我必须重新考虑这一点,我会以“不”作为答案,无论如何,谢谢。
  • @user1797612:我想我还是不明白你到底在问什么。您似乎希望编译器以某种方式知道 foo() 的返回类型应该是什么,而该信息从未在任何地方提供给它。
  • @user1797612:是的,函数确实是在变量之前声明的。这就是为什么您需要一些机制将变量的类型传递回函数的原因。这可以通过如图所示的模板来完成。
  • 模板做你想做的事,而这个关键字没有,它看起来像它,但正如你所看到的,你不会让 decltype 为你工作。
  • @user1797612:这里的根本问题是,如果函数在变量之前声明,它不能隐式使用变量的类型。以前没有提供的第三种解决方案是 typedef 顶部要使用的类型,然后在函数定义和变量声明中使用该 typedef。我会用一个例子来更新我的答案。
【解决方案3】:

使用 C++1y,您将能够做到这一点:

#include <iostream>

auto foo()
{
  return 4.3f;
}

int main(int argc, char* argv[])
{
  auto a = 5.5f;
  std::cout << foo() << std::endl;
  return(0);
}

您已经可以使用 lambda 函数完成。

这是在 g++-4.8 中使用 std=c++1y 标志实现的。

我在这里回答:C++11 auto and function return types

【讨论】:

  • 这完全不同,foo() 上的 auto 关键字根据 foo() 的返回类型而不是 a 的类型分配类型,这正是我想要的.
  • @user1797612:但在大多数情况下,它的行为方式与您所要求的几乎相同。
【解决方案4】:

这就是你所追求的吗?它应该编译:

#include <iostream>

const float foo() 
{
  return 4.3f;
}

int main(int argc, char* argv[])
{
  decltype(foo()) a;
  a = foo();
  std::cout << a << std::endl;
  return(0);
}

【讨论】:

  • 不,我的意思是赋予变量更多的灵活性,而不是方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多