原型的 C++ 模板等价性
C++ Template Equivalence of Prototypes
以下编译按预期运行和执行:
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <type_traits>
class Freaky {
public:
template<
typename UNSIGNED_TYPE,
typename std::enable_if<(sizeof(UNSIGNED_TYPE)>=sizeof(int)),int>::type X = 0
>
static UNSIGNED_TYPE copyThing(int x) ;
};
template<
typename UNSIGNED_TYPE,
typename std::enable_if<(sizeof(UNSIGNED_TYPE)>=sizeof(int)),int>::type X
>
UNSIGNED_TYPE Freaky::copyThing(int x) {
UNSIGNED_TYPE r(0);
std::memcpy(&r,&x,sizeof(int));//Please ignore. Not the point of the question...
return r;
}
int main(int argc, char*argv[]) {
std::cout << "The answer is ... " <<
Freaky::copyThing<unsigned long>(10)<<std::endl;
return EXIT_SUCCESS;
}
样本输出(实际输出可能取决于字节顺序和整数大小):
The answer is .... 10
以下将无法编译并抱怨 copyThing()
的实现原型与 class 中声明的原型不匹配。
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <type_traits>
class Freaky {
public:
template<
typename UNSIGNED_TYPE,
typename std::enable_if<(sizeof(UNSIGNED_TYPE)>=sizeof(int)),int>::type X = 0
>
static UNSIGNED_TYPE copyThing(int x) ;
};
template<
typename UNSIGNED_TYPE,
typename std::enable_if<(sizeof(int)<=sizeof(UNSIGNED_TYPE)),int>::type X
>
UNSIGNED_TYPE Freaky::copyThing(int x) {
UNSIGNED_TYPE r(0);
std::memcpy(&r,&x,sizeof(int));//Please ignore. Not the point of the question...
return r;
}
int main(int argc, char*argv[]) {
std::cout << "The answer is ... " <<
Freaky::copyThing<unsigned long>(10)<<std::endl;
return EXIT_SUCCESS;
}
两者之间的唯一区别是 sizeof(UNSIGNED_TYPE)>=sizeof(int)
在那个实现中被替换为 sizeof(int)<=sizeof(UNSIGNED_TYPE)
。
显然这两个语句在语义上是等价的。
我在哪里可以找到关于如何确定模板原型相等的正式定义?
这显然是某种程度的词汇对等,而不是语义对等。
我找不到标准的任何部分明确指定何时重新声明 class 模板(或 class 模板及其在成员的外联定义中的说明符)都一样。
编译器实际上遵循函数模板重新声明的规则,如 C++11 14.5.6.1/5+6 中指定:
5 Two expressions involving template parameters are considered equivalent if two function definitions containing the expressions would satisfy the one definition rule (3.2), except [template parameter renaming].
6 Two function template are equivalent if they are declared in the same scope, have the same name, have identical template parameter lists, and have return types and parameter lists that are equivalent using the rules described above to compare expressions involving template parameters.
不过,我找不到任何规则使它适用于非类型模板参数类型中的表达式,以重新声明 class 模板。
以下编译按预期运行和执行:
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <type_traits>
class Freaky {
public:
template<
typename UNSIGNED_TYPE,
typename std::enable_if<(sizeof(UNSIGNED_TYPE)>=sizeof(int)),int>::type X = 0
>
static UNSIGNED_TYPE copyThing(int x) ;
};
template<
typename UNSIGNED_TYPE,
typename std::enable_if<(sizeof(UNSIGNED_TYPE)>=sizeof(int)),int>::type X
>
UNSIGNED_TYPE Freaky::copyThing(int x) {
UNSIGNED_TYPE r(0);
std::memcpy(&r,&x,sizeof(int));//Please ignore. Not the point of the question...
return r;
}
int main(int argc, char*argv[]) {
std::cout << "The answer is ... " <<
Freaky::copyThing<unsigned long>(10)<<std::endl;
return EXIT_SUCCESS;
}
样本输出(实际输出可能取决于字节顺序和整数大小):
The answer is .... 10
以下将无法编译并抱怨 copyThing()
的实现原型与 class 中声明的原型不匹配。
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <type_traits>
class Freaky {
public:
template<
typename UNSIGNED_TYPE,
typename std::enable_if<(sizeof(UNSIGNED_TYPE)>=sizeof(int)),int>::type X = 0
>
static UNSIGNED_TYPE copyThing(int x) ;
};
template<
typename UNSIGNED_TYPE,
typename std::enable_if<(sizeof(int)<=sizeof(UNSIGNED_TYPE)),int>::type X
>
UNSIGNED_TYPE Freaky::copyThing(int x) {
UNSIGNED_TYPE r(0);
std::memcpy(&r,&x,sizeof(int));//Please ignore. Not the point of the question...
return r;
}
int main(int argc, char*argv[]) {
std::cout << "The answer is ... " <<
Freaky::copyThing<unsigned long>(10)<<std::endl;
return EXIT_SUCCESS;
}
两者之间的唯一区别是 sizeof(UNSIGNED_TYPE)>=sizeof(int)
在那个实现中被替换为 sizeof(int)<=sizeof(UNSIGNED_TYPE)
。
显然这两个语句在语义上是等价的。 我在哪里可以找到关于如何确定模板原型相等的正式定义?
这显然是某种程度的词汇对等,而不是语义对等。
我找不到标准的任何部分明确指定何时重新声明 class 模板(或 class 模板及其在成员的外联定义中的说明符)都一样。
编译器实际上遵循函数模板重新声明的规则,如 C++11 14.5.6.1/5+6 中指定:
5 Two expressions involving template parameters are considered equivalent if two function definitions containing the expressions would satisfy the one definition rule (3.2), except [template parameter renaming]. 6 Two function template are equivalent if they are declared in the same scope, have the same name, have identical template parameter lists, and have return types and parameter lists that are equivalent using the rules described above to compare expressions involving template parameters.
不过,我找不到任何规则使它适用于非类型模板参数类型中的表达式,以重新声明 class 模板。