C++ g++;不';如果复制构造函数是模板化的,是否调用它?

C++ g++;不';如果复制构造函数是模板化的,是否调用它?,c++,templates,C++,Templates,tl;dr:如果复制构造函数前面有template,并且构造函数签名中使用了Something,则不会调用该构造函数 概念证明(): 注意复制构造函数中的是如何不打印的 使复制构造函数非模板化(即删除签名中的模板并将相关更改为T)可以解决我的问题 $ g++ --version g++ (GCC) 6.2.1 20160830 编译和执行命令: g++ -Wall -Wextra -pedantic -std=c++11 -O2 -Wshadow -Wformat=2 -Wfloat-equ

tl;dr:如果复制构造函数前面有
template
,并且构造函数签名中使用了
Something
,则不会调用该构造函数


概念证明():

注意复制构造函数中的
是如何不打印的

使复制构造函数非模板化(即删除签名中的
模板
并将
相关
更改为
T
)可以解决我的问题

$ g++ --version
g++ (GCC) 6.2.1 20160830
编译和执行命令:

g++ -Wall -Wextra -pedantic -std=c++11 -O2 -Wshadow -Wformat=2 -Wfloat-equal -Wconversion -Wlogical-op -Wcast-qual -Wcast-align -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC -D_FORTIFY_SOURCE=2 -fsanitize=address -fsanitize=undefined -fno-sanitize-recover -fstack-protector "test.cpp" -o "test" && "test"

这是怎么回事?

函数模板永远不能是复制构造函数,即使实例化的类型显然会使其与复制构造函数的预期签名相匹配。参见[class.copy/2]:

如果类X的非模板构造函数的第一个参数类型为X&、const X&、volatile X&或const volatile X&,并且没有其他参数,或者所有其他参数都有默认参数,则该类X的非模板构造函数是复制构造函数

如果没有用户声明的复制构造函数(有时可能定义为已删除),则所有类都有一个隐式生成的复制构造函数,并带有签名:

Test(Test const &) = default;
当您编写
测试t2(t1)时,重载解析选择复制构造函数而不是模板函数,因为在所有其他条件相同的情况下,非模板比模板更可取

请注意,如果您将模板函数更改为
Test(Test&t)
,那么现在将通过复制构造函数选择它:“所有其他事物”不再相等,与添加
const
以匹配复制构造函数的转换相比,最好实例化模板以精确匹配
Test

引用

类T的复制构造函数是一个非模板构造函数,其第一个参数是
T&
const T&
volatile T&
const volatile T&
,或者没有其他参数,或者其余参数都有默认值

因此,构造函数既不能作为模板,也不能具有正确的参数类型

g++ -Wall -Wextra -pedantic -std=c++11 -O2 -Wshadow -Wformat=2 -Wfloat-equal -Wconversion -Wlogical-op -Wcast-qual -Wcast-align -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC -D_FORTIFY_SOURCE=2 -fsanitize=address -fsanitize=undefined -fno-sanitize-recover -fstack-protector "test.cpp" -o "test" && "test"
Test(Test const &) = default;