1

我从另一段代码中遇到了这个问题,但归结为以下代码段:

#include <iostream>

struct A
{
    template <int I>
    A() : _i{I} {}

    int _i;
};

int main()
{
    A* ptr = new A; // how to call the constructor with a specific template argument ?

    return 0;    
}

这不会令人惊讶地引发以下错误:

clang++ -std=c++17 -Wall main.cpp && ./a.out;

main.cpp:13:18: error: no matching constructor for initialization of 'A'

    A* ptr = new A; // how to call the constructor with a specific template argument ?
                 ^
main.cpp:6:5: note: candidate template ignored: couldn't infer template argument 'I'

    A() : _i{I} {}
    ^
main.cpp:3:8: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided

struct A
       ^

这看起来像是以前会遇到一千次的问题,但我在 cppreference 或 SO 上找不到解决方案。

如何在新表达式中指定构造函数的模板参数?

4

3 回答 3

4

不幸的是,您不能为构造函数模板显式指定模板参数,除非可以推断出模板参数,否则无法使用该模板参数。[temp.arg.explicit]/8

[注:因为显式模板参数列表跟在函数模板名之后,而且构造函数模板([class.ctor])的命名没有使用函数名([class.qual]),所以无法提供显式模板这些函数模板的参数列表。——尾注]

于 2019-08-16T13:08:29.240 回答
2

你必须推断它。你不能明确地传递它们。

您的示例的一种解决方案是:

struct A
{
    template <int I>
    A(std::integral_constant<int, I>) : _i{I} {}

    int _i;
};

auto a = A{std::integral_constant<int, 4>{}};
于 2019-08-16T13:12:38.330 回答
1

正如我在评论中提到的,一种可能的解决方法是使用继承:

struct A
{
    int _i;
};

template<int I>
struct B : A
{
    B() : A::_i(I) {}
};

...

A* a = new B<10>;
于 2019-08-16T13:11:21.493 回答