简体   繁体   English

功能模板参数的类型推导

[英]Type deduction of function template parameters

I have some questions concerning function templates. 我对功能模板有一些疑问。

My plan was to build a wrapper which derives from a user-defined class and not only exports the public functions of that class but also its constructors. 我的计划是构建一个包装程序,该包装程序从用户定义的类派生,不仅导出该类的公共函数,还导出其构造函数。 So I decided I would use multiple constructor templates (which I presume work exactly the same as function templates) with 1 to n parameters to satisfy most constructors needs. 因此,我决定使用带有1到n个参数的多个构造函数模板(我假定其工作原理与功能模板完全相同)来满足大多数构造函数的需求。

These would than simply call the constructor and do something else afterwards, like this: 这些将不只是简单地调用构造函数,然后再执行其他操作,如下所示:

template <class T>
class Wrapper : public T
{
    public:
        template <class U>
        Wrapper(U &u) : T(u) { doSomething(); }

        template <class U, class V>
        Wrapper(U &u, V &v) : T(u,v) { doSomething(); }

        ...
};

My intent is to register the instance within the Wrapper-Ctor somewhere else and, from that point on, it can receive calls to virtual functions defined in T. 我的目的是在Wrapper-Ctor中的其他位置注册该实例,从那时起,它可以接收对T中定义的虚函数的调用。

I had to use the reference operator in the code above, in order to guarantee that my Wrapper-Ctor does not have any side-effects on the parameters that were passed (copy-construction). 我必须在上面的代码中使用引用运算符,以确保我的Wrapper-Ctor对传递的参数(复制构造)没有任何副作用。

To my surprise this always worked, except for temporaries, which is the reason why I am confused about the types that are inferred by the compiler in this situation. 令我惊讶的是,除临时选项外,这始终有效,这就是为什么我对这种情况下编译器推断的类型感到困惑的原因。 To simplify the situation I tried to do something similiar via a template function: 为了简化这种情况,我尝试通过模板函数进行类似的操作:

template <class T>
void foo(T &t)
{
    int x = ""; // intentional error
}

Calling the function like this: 像这样调用函数:

std::string a; 
std::string &b = a;
foo(b);

To my surprise the compiler denotes [T = std::string] in its error message. 令我惊讶的是,编译器在其错误消息中表示[T = std :: string]。 I would have expected for this to be [T = std::string&], which would have caused passing a reference-to-reference, which is invalid. 我曾以为这是[T = std :: string&],这将导致传递引用到引用,这是无效的。

So, why does the compiler deduce a value-type in this situation? 那么,为什么在这种情况下编译器会推断出值类型呢? Is it even possible to create a Wrapper-Ctor that does what I want, does not have any side-effects on the parameters and also accepts temporaries? 甚至有可能创建一个Wrapper-Ctor来满足我的要求,该参数对参数没有任何副作用,并且可以接受临时对象吗?

Thanks alot! 非常感谢!

It looks like the C++ spec explicitly states that this is the intended behavior. 看起来C ++规范明确声明这是预期的行为。 Specifically, if you have a template function that takes in a parameter P that depends on a template type argument, if P is a reference, then the underlying type of the reference, rather than the reference type, is used to determine what type should be used for P (see §14.8.2.1/2). 具体来说,如果您有一个模板函数接受依赖于模板类型实参的参数P ,则如果P是引用,则使用引用的基础类型(而不是引用类型)来确定应使用的类型。用于P (参见§14.8.2.1/ 2)。 Moreover, this same section says that const and volatile qualifiers are ignored during this step, so the const ness can be inferred automatically. 此外,同一部分还说在此步骤中会忽略constvolatile限定词,因此可以自动推断出const含义。

在C ++ 03中,如果没有为const和non-const参数的每个组合手动进行重载,就不可能提供这样的东西。

No expression ever has reference type. 没有表达式具有引用类型。 Therefor, when argument deduction deduces against the argument expression type, it cannot make a distinction between a and b because the arguments a and b both have the same type. 因此,当自变量推导推导自变量表达类型时,由于自变量ab都具有相同的类型,因此无法区分ab

Refer to [expr]p5 in the spec 请参阅规格中的[expr] p5

If an expression initially has the type "reference to T" (8.3.2, 8.5.3), the type is adjusted to T prior to any further analysis. 如果表达式最初的类型为“对T的引用”(8.3.2,8.5.3),则在进行任何进一步分析之前,将类型调整为T。

Somewhat late, but since I don't think this was answered completely... 有点晚了,但是由于我认为这还没有完全解决...

For template parameter deduction, see the previous answers. 有关模板参数的推导,请参见前面的答案。

For your problem with temporaries, make the parameters const references (as in Wrapper(const U&)). 对于临时问题,请使参数const引用(如在Wrapper(const U&)中一样)。

The thing is, temporaries are rvalues. 问题是,临时属性是右值。 The standard states that non-const references can only be bound to lvalues. 该标准指出,非const引用只能绑定到左值。 Therefore, a standards compliant compiler won't let you pass temporaries(rvalues) as arguments to non-const reference parameters. 因此,符合标准的编译器将不允许您将临时变量(rvalues)作为参数传递给非const参考参数。 (This doesn't have anything to do with templates in particular, it's a general rule). (这与模板无关,这是一般规则)。

This is to the best of my knowledge, so take it with a bit of scepticism. 据我所知,所以对此持怀疑态度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM