繁体   English   中英

为什么这样调用构造函数时模板参数推导失败?

[英]Why does template parameter deduction fail when calling the constructor like this?

以下内容无法编译:

struct S {
    template <class T> S(T) {}
};
void f(int) {}
int main() {
    S(f);
}

g ++-4.9说

template.cpp: In function ‘int main()’:
template.cpp:6:8: error: no matching function for call to ‘S::S()’
     S(f);
        ^
template.cpp:6:8: note: candidates are:
template.cpp:2:24: note: template<class T> S::S(T)
     template <class T> S(T) {}
                        ^
template.cpp:2:24: note:   template argument deduction/substitution failed:
template.cpp:6:8: note:   candidate expects 1 argument, 0 provided
     S(f);
        ^
template.cpp:1:8: note: constexpr S::S(const S&)
 struct S {
        ^
template.cpp:1:8: note:   candidate expects 1 argument, 0 provided
template.cpp:1:8: note: constexpr S::S(S&&)
template.cpp:1:8: note:   candidate expects 1 argument, 0 provided

铛给出了类似的错误。

另一方面,将编译以下内容:

struct S {
    template <class T> S(T) {}
};
void f(int) {}
int main() {
    S s = S(f); // this line was changed
}

那么这是怎么回事?

问题

您编写的代码并不代表您的实际意思,实际上是在声明名称为f的类型S的变量; 不是使用f作为参数构造S类型的未命名实体。

注意:当您将行更改为S s = S(f)您将声明一个名为s的类型为S的变量,并使用临时S(f)初始化(即S副本构造函数将用于初始化s )。


解决方案

将类型包装在括号中,或使用统一初始化 (在C ++ 11中引入)。

(S) (f); // creates a temporary of type S initialized with `f`

S { f }; // c++11

原因

标准( n3797 )表示,声明变量时T(x)等于T x ,如以下部分所示:

8.3p6 声明符的含义 [dcl.meaning] 意义 [dcl.meaning]

在声明TDD具有以下形式

 ( D1 ) 

所包含的说明符-ID的类型是一样的,在声明的说明符包含-ID

 T D1 

括号不会更改嵌入的声明符id的类型,但是可以更改复杂声明符的绑定。

用你对struct S的定义

int main() {

    S(f);                                            //  1 <-----+
    S s(f);           //  2 <-------+                //          +---- SAME
    S s1 ;            //            +---- SAME       //  3 <-----+
    S s2 = S(f) ;     //  4 <-------+

}
  • 1和3分别声明类型S的变量fs1需要初始化的构造函数
  • 2和4使用复制构造函数分别构造类型S的变量ss2 (请注意,这里的f不是您的函数名)

暂无
暂无

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

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