你能在不提供参数的情况下基于函数进行类型推断吗?

Can you do type inference based on a function, without providing parameters?

提问人:paxdiablo 提问时间:10/20/2023 更新时间:10/20/2023 访问量:94

问:

有时,在不想显式指定类型的情况下创建正确类型的变量非常有用,尤其是当类型是复杂类型(如 (1))时。这是几乎总是自动指南的核心。std::map<std::string, std::tuple<int, SomeStructure>>

对于初始化变量的情况,可以使用:

auto a = 3.14159f;                          // float.
auto a = function_returning_type(1, 2, 3);  // whatever that function returns.

如果你不想初始化它,你可以用它来定义它:decltype

int a;
decltype(a) b;  // integer


float c();
decltype(c()) d;  // float

如果您想将类型基于某些函数返回的内容而不是已经存在的变量,则最后一个特别方便。但是,如果函数的唯一重载需要大量参数,则似乎需要您提供这些参数:

int a(const char *, int, float);
decltype(a("", 7, 4.2)) b;        // okay
decltype(a()) c;                  // not okay

第二个示例给出的内容如下:

error: too few arguments to function ‘int a(const char *, int, float)’
    decltype(a()) c;
               ^

尽管在这种情况下不需要参数,因为编译器可以在没有参数的情况下确定这一点。无论为函数提供多少重载,函数的返回类型都是相同的。

所以我的第一个问题是:我是否误解了这样做的必要性?换句话说,我需要提供参数是否有实际原因?

其次(这是真正的问题),有没有一种方法不需要我提供这些人为参数?


(1) 是的,我知道我可以做类似的事情,但这并不总是我的代码。using ShortType = std::map<std::string, std::tuple<int, SomeStructure>>;

C++ 自动 解码类型

评论


答:

5赞 Caleth 10/20/2023 #1

无论为函数提供多少重载,函数的返回类型都是相同的。

不,无论如何都不是。以下是完全有效的重载。

int getValue(float);
float getValue(int);

有没有办法做到这一点,不需要我提供这些人为参数?

仅当没有过载时。

std::invoke_result_t<decltype(a)> c;
4赞 463035818_is_not_an_ai 10/20/2023 #2

您的问题基于一个错误的前提,即所有重载都具有相同的返回类型。这是不正确的。我想你把它混淆了:你不能只根据返回类型重载一个函数。

您不能这样做:

int foo();
float foo();    // error: cannot overload based on return type alone

但你可以这样做:

int bar(int);
float bar(float);

因此,您需要参数的类型来选择重载。您不需要值:

#include <utility>

int a(const char *, int, float);
int main() {

using t1 = decltype(a("", 7, 4.2));        // okay
using t2 = decltype(a(std::declval<const char*>(),
                      std::declval<int>(),
                      std::declval<float>()));  // okay !
}

std::declval可以在未评估的上下文中使用(例如)来获取引用。说到这里不需要它,我也可以使用或.但是,它更通用,也适用于没有默认构造函数的类型。decltypefloat{}int{}std::declval

评论

0赞 Red.Wave 10/20/2023
如果参数类型具有复杂的构造函数参数并且缺少默认构造函数,则无法编写。 没问题;它演示了 的用法,应该得到更多的关注。t1t2std::declval
0赞 463035818_is_not_an_ai 10/20/2023
@Red.Wave 只是 OPs 代码的复制粘贴。整个问题是关于不使用 ,但如果你认为可以更清楚,我不介意你编辑t1t1
0赞 Red.Wave 10/20/2023
撇开超载规则不谈,我猜 OP 只是不知道.std::declval