gpt4 book ai didi

c++ - 在模板中使用模板别名而不是模板

转载 作者:可可西里 更新时间:2023-11-01 15:18:11 24 4
gpt4 key购买 nike

来自上一个问题:

Doing a static_assert that a template type is another template

Andy Prowl 为我提供了这段代码,它允许我static_assert一个模板类型是另一个模板类型:

template<template<typename...> class TT, typename... Ts>
struct is_instantiation_of : public std::false_type { };

template<template<typename...> class TT, typename... Ts>
struct is_instantiation_of<TT, TT<Ts...>> : public std::true_type { };

template<typename T>
struct foo {};

template<typename FooType>
struct bar {
static_assert(is_instantiation_of<foo,FooType>::value, ""); //success
};

int main(int,char**)
{
bar<foo<int>> b; //success
return 0;
}

效果很好。

但是如果我像这样更改代码以使用 foo 的别名,事情就会变糟:

template<template<typename...> class TT, typename... Ts>
struct is_instantiation_of : public std::false_type { };

template<template<typename...> class TT, typename... Ts>
struct is_instantiation_of<TT, TT<Ts...>> : public std::true_type { };

template<typename T>
struct foo {};

//Added: alias for foo
template<typename T>
using foo_alt = foo<T>;

template<typename FooType>
struct bar {
//Changed: want to use foo_alt instead of foo here
static_assert(is_instantiation_of<foo_alt,FooType>::value, ""); //fail
};

int main(int,char**) {
//both of these fail:
bar<foo<int>> b;
bar<foo_alt<int>> b2;

return 0;
}

这能解决吗?

最佳答案

不,它无法解决(至少在不显着改变设计的情况下)。问题是模板别名没有被推导,如 C++11 标准第 14.5.7/2 段所述:

When a template-id refers to the specialization of an alias template, it is equivalent to the associated type obtained by substitution of its template-arguments for the template-parameters in the type-id of the alias template. [ Note: An alias template name is never deduced.—end note ]

段落还提供了一个例子:

[ Example:

template<class T> struct Alloc { / ... / };
template<class T> using Vec = vector<T, Alloc<T>>;
Vec<int> v; // same as vector<int, Alloc<int>> v;

...

template<template<class> class TT>
void f(TT<int>);
f(v); // error: Vec not deduced <=== Relevant

...

end example ]

在您的具体情况下,问题是当尝试匹配部分特化时,编译器不会推断您的类型是 foo_alt 的实例(因为 foo_alt 是别名模板的名称),然后选择主模板。

如果你想使用别名模板,你将不得不放弃一些通用性并创建一个特定于 foo 的类型特征:

#include <type_traits>

template<typename T>
struct foo {};

template<typename T>
struct is_instantiation_of_foo : std::false_type { };

template<typename...Ts>
struct is_instantiation_of_foo<foo<Ts...>> : std::true_type { };

然后你可以这样使用:

template<typename FooType>
struct bar {
static_assert(is_instantiation_of_foo<FooType>::value, ""); //fail
};

现在,以下程序中的所有断言都不会触发:

template<typename T>
using foo_alt = foo<T>;

int main(int,char**) {
// None of these fail:
bar<foo<int>> b;
bar<foo_alt<int>> b2;

return 0;
}

这是一个live example .

关于c++ - 在模板中使用模板别名而不是模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17392621/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com