Foo 的参数有默认值,因此在 main() 中我可以做 Foo();创建一个 Foo ,它将具有默认的模板参数。但是我不能在模板参数中使用:
template <typename T = double, int a =2, int b = 3>
struct Foo {};
//cannot deduce template arguments for ‘Foo’ from ()
template <typename FooType = Foo()> // <-- Error
struct TemplatedStructTakingAFooType
{
};
int main()
{
Foo(); // Foo type is deduced to be default values, ie.,
//Foo<double, 2, 3>;
decltype(Foo()); // Compiler knows the type
}
在我的 Visual Studio 编译器中,它以红色突出显示区域,指示错误,但可以编译。在 C++17 下的 onlineGDB 上编译失败并出现上述错误。这是允许的吗?有什么理由不应该吗?
编辑:我意识到使用是多么愚蠢,因为 Foo() 不是一种类型,但 '= Foo' 和 '= decltype(Foo())' 也不起作用。
答案 0 :(得分:5)
问题在于 Foo
不是类型,而是类型的模板。
您需要在此处指定一个实际类型,它需要模板尖括号,Foo<>
是类型 Foo<double, 2, 3>
:
typename FooType = Foo<>
答案 1 :(得分:3)
Foo()
不是一个类型所以需要 decltype
:
typename FooType = decltype(Foo())
答案 2 :(得分:0)
有些东西必须改变,因为你在混合想法。
您可以将 Foo 作为其中之一传递
以下是每个示例:
template <typename T = double, int a =2, int b = 3>
struct Foo {};
// As a type. The caller has secided what the template arguments that Foo
// will have, or by allowing them to default, has chosen the defaults.
template <typename FooType = decltype(Foo{})>
struct A
{
};
// Here FooType is passed as a template. Inside B, you'd need to
// provide it template parameters to instantiate it.
template <template <typename T, int, int> typename Foo2 = Foo>
struct B
{
using F = Foo2<float, 3, 4>;
};
// As a user-defined non-type template parameter
// This only works in C++20, since it's a new feature
template <Foo f>
struct C
{
};
// And finally, CTAD to with deduced arguments for Foo as a user-defined
// non-type tempalte parameter, with friendly constructor syntax. (For the
// caller, not for the reader of this monstrosity).
// The deduction guide allows passing an instance of Foo<T, a, b> to the
// constructor and allowing it to match types for T, a, b for the struct.
template <typename T, int a, int b, Foo<T, a, b> f>
struct D
{
D(Foo<T, a, b>) { }
};
template <typename T, int a, int b> D(Foo<T, a, b>) -> D<T, a, b, Foo<T, a, b>{}>;
int main()
{
A a; // default
A<Foo<float, 5, 9>> a2; // give types to Foo given to A
B<Foo> b; // Pass Foo to b as a template-template param
C<Foo{}> c; // Pass instance of Foo with default args
Foo<short, 99, 0> customFoo;
D d(customFoo); // Pass instance to constructor(!) to
// set template args even when Foo is not default.
}