C++ 如何在使用参数推断时停止模板递归?
此代码任务包含一个常量字符[],并查找最后一个斜杠的位置:C++ 如何在使用参数推断时停止模板递归?,c++,arrays,templates,c++14,c++17,C++,Arrays,Templates,C++14,C++17,此代码任务包含一个常量字符[],并查找最后一个斜杠的位置: #包括 我通过使用类部分模板专门化来修复它。我没有使用函数部分模板专门化,因为它是不允许的: #定义静态断言(…)静态断言(uu VA_ARGS_uu,35; VA_ARGS_uu) 模板 结构Findlastslash { 模板 静态constexpr int start(const char(&path)[PathLength]) { constexpr const int end=路径长度-路径索引; 返回(路径索引>=0&&
#包括
我通过使用类部分模板专门化来修复它。我没有使用函数部分模板专门化,因为它是不允许的:
#定义静态断言(…)静态断言(uu VA_ARGS_uu,35; VA_ARGS_uu)
模板
结构Findlastslash
{
模板
静态constexpr int start(const char(&path)[PathLength])
{
constexpr const int end=路径长度-路径索引;
返回(路径索引>=0&&path[end]!='/'&&path[end]!='\')
?Findlastslash:开始(路径):(结束);
}
};
模板
结构Findlastslash<1>
{
模板
静态constexpr int start(const char(&path)[PathLength]){
返回0;
}
};
模板
constexpr const int startfindlastsslash(const char(&path)[路径长度]){
返回Findlastslash::开始(路径);
}
int main(int argc,char const*argv[]
{
静态断言(startfindlastslash(“h/bye”)==1);
}
这是展开的模板:
clang++-Xclang-ast print-fsyntax only--std=c++14 test\u debugger.cpp>main.exe
template <int PathIndex>
struct Findlastslash
{
template <int PathLength>
static constexpr int start(const char (&path)[PathLength])
{
constexpr int end = PathLength - PathIndex;
return (PathIndex >= 0 && path[end] != '/' && path[end] != '\\')
? Findlastslash<PathIndex - 1>::start(path) : (end);
}
};
template<>
struct Findlastslash<6>
{
template <int PathLength>
static constexpr int start(const char (&path)[PathLength]);
template<> static constexpr int start<6>(const char (&path)[6])
{
constexpr int end = 6 - 6;
return (6 >= 0 && path[end] != '/' && path[end] != '\\')
? Findlastslash<6 - 1>::start(path) : (end);
};
};
template<>
struct Findlastslash<5>
{
template <int PathLength>
static constexpr int start(const char (&path)[PathLength]);
template<> static constexpr int start<6>(const char (&path)[6])
{
constexpr int end = 6 - 5;
return (5 >= 0 && path[end] != '/' && path[end] != '\\')
? Findlastslash<5 - 1>::start(path) : (end);
};
};
template<>
struct Findlastslash<4>
{
template <int PathLength>
static constexpr int start(const char (&path)[PathLength]);
template<> static constexpr int start<6>(const char (&path)[6])
{
constexpr int end = 6 - 4;
return (4 >= 0 && path[end] != '/' && path[end] != '\\')
? Findlastslash<4 - 1>::start(path) : (end);
};
};
template<>
struct Findlastslash<3>
{
template <int PathLength>
static constexpr int start(const char (&path)[PathLength]);
template<> static constexpr int start<6>(const char (&path)[6])
{
constexpr int end = 6 - 3;
return (3 >= 0 && path[end] != '/' && path[end] != '\\')
? Findlastslash<3 - 1>::start(path) : (end);
};
};
template<>
struct Findlastslash<2>
{
template <int PathLength>
static constexpr int start(const char (&path)[PathLength]);
template<> static constexpr int start<6>(const char (&path)[6])
{
constexpr int end = 6 - 2;
return (2 >= 0 && path[end] != '/' && path[end] != '\\')
? Findlastslash<2 - 1>::start(path) : (end);
};
};
template<>
struct Findlastslash<1>
{
template <int PathLength>
static constexpr int start(const char (&path)[PathLength]) {
return 0;
}
template<>
static constexpr int start<6>(const char (&path)[6]) {
return 0;
}
};
template <int PathLength>
constexpr const int startfindlastslash(const char (&path)[PathLength]) {
return Findlastslash<PathLength>::start(path);
}
template<>
constexpr const int startfindlastslash<6>(const char (&path)[6]) {
return Findlastslash<6>::start(path);
}
int main(int argc, const char *argv[]) {
static_assert(startfindlastslash("h/bye")==1, "startfindlastslash( \"h/bye\" )==1");
}
模板
结构Findlastslash
{
模板
静态constexpr int start(const char(&path)[PathLength])
{
constexpr int end=路径长度-路径索引;
返回(路径索引>=0&&path[end]!='/'&&path[end]!='\')
?Findlastslash::开始(路径):(结束);
}
};
模板
结构Findlastslash
{
模板
静态constexpr int start(const char(&path)[PathLength]);
模板静态constexpr int start(const char(&path)[6])
{
constexpr int end=6-6;
return(6>=0&&path[end]!='/'&&path[end]!='\')
?Findlastslash::开始(路径):(结束);
};
};
模板
结构Findlastslash
{
模板
静态constexpr int start(const char(&path)[PathLength]);
模板静态constexpr int start(const char(&path)[6])
{
constexpr int end=6-5;
return(5>=0&&path[end]!='/'&&path[end]!='\')
?Findlastslash::开始(路径):(结束);
};
};
模板
结构Findlastslash
{
模板
静态constexpr int start(const char(&path)[PathLength]);
模板静态constexpr int start(const char(&path)[6])
{
constexpr int end=6-4;
return(4>=0&&path[end]!='/'&&path[end]!='\')
?Findlastslash::开始(路径):(结束);
};
};
模板
结构Findlastslash
{
模板
静态constexpr int start(const char(&path)[PathLength]);
模板静态constexpr int start(const char(&path)[6])
{
constexpr int end=6-3;
return(3>=0&&path[end]!='/'&&path[end]!='\')
?Findlastslash::开始(路径):(结束);
};
};
模板
结构Findlastslash
{
模板
静态constexpr int start(const char(&path)[PathLength]);
模板静态constexpr int start(const char(&path)[6])
{
constexpr int end=6-2;
返回(2>=0&&path[end]!='/'&&path[end]!='\')
?Findlastslash::开始(路径):(结束);
};
};
模板
结构Findlastslash
{
模板
静态constexpr int start(const char(&path)[PathLength]){
返回0;
}
模板
静态constexpr int start(const char(&path)[6]){
返回0;
}
};
模板
constexpr const int startfindlastsslash(const char(&path)[路径长度]){
返回Findlastslash::start(路径);
}
模板
constexpr const int startfindlastsslash(const char(&path)[6]){
返回Findlastslash::start(路径);
}
int main(int argc,const char*argv[]{
静态断言(startfindlastslash(“h/bye”)==1,“startfindlastslash”(“h/bye”)==1”);
}
我通过使用类部分模板专门化来修复它。我没有使用函数部分模板专门化,因为它是不允许的:
#定义静态断言(…)静态断言(uu VA_ARGS_uu,35; VA_ARGS_uu)
模板
结构Findlastslash
{
模板
静态constexpr int start(const char(&path)[PathLength])
{
constexpr const int end=路径长度-路径索引;
返回(路径索引>=0&&path[end]!='/'&&path[end]!='\')
?Findlastslash:开始(路径):(结束);
}
};
模板
结构Findlastslash<1>
{
模板
静态constexpr int start(const char(&path)[PathLength]){
返回0;
}
};
模板
constexpr const int startfindlastsslash(const char(&path)[路径长度]){
返回Findlastslash::开始(路径);
}
int main(int argc,char const*argv[]
{
静态断言(startfindlastslash(“h/bye”)==1);
}
这是展开的模板:
clang++-Xclang-ast print-fsyntax only--std=c++14 test\u debugger.cpp>main.exe
template <int PathIndex>
struct Findlastslash
{
template <int PathLength>
static constexpr int start(const char (&path)[PathLength])
{
constexpr int end = PathLength - PathIndex;
return (PathIndex >= 0 && path[end] != '/' && path[end] != '\\')
? Findlastslash<PathIndex - 1>::start(path) : (end);
}
};
template<>
struct Findlastslash<6>
{
template <int PathLength>
static constexpr int start(const char (&path)[PathLength]);
template<> static constexpr int start<6>(const char (&path)[6])
{
constexpr int end = 6 - 6;
return (6 >= 0 && path[end] != '/' && path[end] != '\\')
? Findlastslash<6 - 1>::start(path) : (end);
};
};
template<>
struct Findlastslash<5>
{
template <int PathLength>
static constexpr int start(const char (&path)[PathLength]);
template<> static constexpr int start<6>(const char (&path)[6])
{
constexpr int end = 6 - 5;
return (5 >= 0 && path[end] != '/' && path[end] != '\\')
? Findlastslash<5 - 1>::start(path) : (end);
};
};
template<>
struct Findlastslash<4>
{
template <int PathLength>
static constexpr int start(const char (&path)[PathLength]);
template<> static constexpr int start<6>(const char (&path)[6])
{
constexpr int end = 6 - 4;
return (4 >= 0 && path[end] != '/' && path[end] != '\\')
? Findlastslash<4 - 1>::start(path) : (end);
};
};
template<>
struct Findlastslash<3>
{
template <int PathLength>
static constexpr int start(const char (&path)[PathLength]);
template<> static constexpr int start<6>(const char (&path)[6])
{
constexpr int end = 6 - 3;
return (3 >= 0 && path[end] != '/' && path[end] != '\\')
? Findlastslash<3 - 1>::start(path) : (end);
};
};
template<>
struct Findlastslash<2>
{
template <int PathLength>
static constexpr int start(const char (&path)[PathLength]);
template<> static constexpr int start<6>(const char (&path)[6])
{
constexpr int end = 6 - 2;
return (2 >= 0 && path[end] != '/' && path[end] != '\\')
? Findlastslash<2 - 1>::start(path) : (end);
};
};
template<>
struct Findlastslash<1>
{
template <int PathLength>
static constexpr int start(const char (&path)[PathLength]) {
return 0;
}
template<>
static constexpr int start<6>(const char (&path)[6]) {
return 0;
}
};
template <int PathLength>
constexpr const int startfindlastslash(const char (&path)[PathLength]) {
return Findlastslash<PathLength>::start(path);
}
template<>
constexpr const int startfindlastslash<6>(const char (&path)[6]) {
return Findlastslash<6>::start(path);
}
int main(int argc, const char *argv[]) {
static_assert(startfindlastslash("h/bye")==1, "startfindlastslash( \"h/bye\" )==1");
}
模板
结构Findlastslash
{
模板
静态constexpr int start(const char(&path)[PathLength])
{
constexpr int end=路径长度-路径索引;
返回(路径索引>=0&&path[end]!='/'&&path[end]!='\')
?Findlastslash::开始(路径):(结束);
}
};
模板
结构Findlastslash
{
模板
静态constexpr int start(const char(&path)[PathLength]);
模板静态constexpr int start(const char(&path)[6])
{
constexpr int end=6-6;
return(6>=0&&path[end]!='/'&&path[end]!='\')
?Findlastslash::开始(路径):(结束);
};
};
模板
结构Findlastslash
{
模板
静态constexpr int start(const char(&path)[PathLength]);
模板静态常数
template <int PathIndex>
struct Findlastslash
{
template <int PathLength>
static constexpr int start(const char (&path)[PathLength])
{
constexpr int end = PathLength - PathIndex;
return (PathIndex >= 0 && path[end] != '/' && path[end] != '\\')
? Findlastslash<PathIndex - 1>::start(path) : (end);
}
};
template<>
struct Findlastslash<6>
{
template <int PathLength>
static constexpr int start(const char (&path)[PathLength]);
template<> static constexpr int start<6>(const char (&path)[6])
{
constexpr int end = 6 - 6;
return (6 >= 0 && path[end] != '/' && path[end] != '\\')
? Findlastslash<6 - 1>::start(path) : (end);
};
};
template<>
struct Findlastslash<5>
{
template <int PathLength>
static constexpr int start(const char (&path)[PathLength]);
template<> static constexpr int start<6>(const char (&path)[6])
{
constexpr int end = 6 - 5;
return (5 >= 0 && path[end] != '/' && path[end] != '\\')
? Findlastslash<5 - 1>::start(path) : (end);
};
};
template<>
struct Findlastslash<4>
{
template <int PathLength>
static constexpr int start(const char (&path)[PathLength]);
template<> static constexpr int start<6>(const char (&path)[6])
{
constexpr int end = 6 - 4;
return (4 >= 0 && path[end] != '/' && path[end] != '\\')
? Findlastslash<4 - 1>::start(path) : (end);
};
};
template<>
struct Findlastslash<3>
{
template <int PathLength>
static constexpr int start(const char (&path)[PathLength]);
template<> static constexpr int start<6>(const char (&path)[6])
{
constexpr int end = 6 - 3;
return (3 >= 0 && path[end] != '/' && path[end] != '\\')
? Findlastslash<3 - 1>::start(path) : (end);
};
};
template<>
struct Findlastslash<2>
{
template <int PathLength>
static constexpr int start(const char (&path)[PathLength]);
template<> static constexpr int start<6>(const char (&path)[6])
{
constexpr int end = 6 - 2;
return (2 >= 0 && path[end] != '/' && path[end] != '\\')
? Findlastslash<2 - 1>::start(path) : (end);
};
};
template<>
struct Findlastslash<1>
{
template <int PathLength>
static constexpr int start(const char (&path)[PathLength]) {
return 0;
}
template<>
static constexpr int start<6>(const char (&path)[6]) {
return 0;
}
};
template <int PathLength>
constexpr const int startfindlastslash(const char (&path)[PathLength]) {
return Findlastslash<PathLength>::start(path);
}
template<>
constexpr const int startfindlastslash<6>(const char (&path)[6]) {
return Findlastslash<6>::start(path);
}
int main(int argc, const char *argv[]) {
static_assert(startfindlastslash("h/bye")==1, "startfindlastslash( \"h/bye\" )==1");
}
template<std::size_t PathLength>
constexpr const int findlastslash(const char (&path)[PathLength])
{
for (std::size_t i = PathLength; i != 0; --i) {
if (path[i - 1] == '/' || path[i - 1] == '\\') {
return i;
}
}
return 0;
}
template<std::size_t PathLength>
constexpr const int findlastslash(const char (&path)[PathLength], std::size_t i = PathLength)
{
return (i == 0)
? 0
: ((path[i - 1] == '/' || path[i - 1] == '\\')
? i
: findlastslash(path, i - 1));
}
template<std::size_t PathLength, std::size_t I = PathLength>
constexpr const int findlastslash(const char (&path)[PathLength])
{
if constexpr (I == 0) {
return 0;
} else {
if (path[I - 1] == '/' || path[I - 1] == '\\') {
return I;
}
return findlastslash<PathLength, I - 1>(path);
}
}
template <std::size_t I> struct findlastslash_impl
{
template <std::size_t PathLength>
constexpr const int findlastslash(const char (&path)[PathLength])
{
if (path[I - 1] == '/' || path[I - 1] == '\\') {
return I;
}
return findlastslash_impl<I - 1>()(path);
}
}
template<> struct findlastslash_impl<0>
{
template<std::size_t PathLength>
constexpr const int findlastslash(const char (&)[PathLength])
{
return 0;
}
};
template<std::size_t PathLength>
constexpr const int findlastslash(const char (&path)[PathLength])
{
return findlastslash_impl<PathLength>()(path);
}
template <std::size_t PathLength>
constexpr const int findlastslash_impl(std::integral_constant<std::size_t, 0>,
const char (&path)[PathLength])
{
return 0;
}
template <std::size_t PathLength, std::size_t I>
constexpr const int findlastslash_impl(std::integral_constant<std::size_t, I>,
const char (&path)[PathLength])
{
if (path[I - 1] == '/' || path[I - 1] == '\\') {
return I;
}
return findlastslash_impl(std::integral_constant<std::size_t, I - 1>(), path);
}
template<std::size_t PathLength>
constexpr const int findlastslash(const char (&path)[PathLength])
{
return findlastslash_impl(std::integral_constant<std::size_t, PathLength>(), path);
}