【问题标题】:C++ invoke explicit template constructorC++ 调用显式模板构造函数
【发布时间】:2016-06-07 00:49:37
【问题描述】:

你能告诉我如何显式调用模板构造函数(在初始化列表中)吗? 例如:

struct T { 
    template<class> T();
};

struct U {
    U() : t<void>() {} //does not work
    T t;
};

谢谢

【问题讨论】:

    标签: c++ templates


    【解决方案1】:

    这是不可能的。该标准还在14.8.1/7

    上对此进行了说明

    [注意:因为显式模板实参列表跟在函数模板名之后,并且因为转换成员函数模板和构造函数成员函数模板是在不使用函数名的情况下调用的,所以没有办法为这些提供显式模板实参列表功能模板。 ]

    解释:这表示:模板参数在函数模板名称后的尖括号中传递,例如std::make_pair&lt;int, bool&gt;。并且构造函数没有自己的名字,但是他们在各种上下文中滥用自己的类名(所以U&lt;int&gt;()的意思是:将&lt;int&gt;传递给类模板U,并通过调用默认构造函数来构造一个对象论据)。因此,不能将模板参数传递给构造函数。

    在您的情况下,您尝试在成员初始化程序中传递模板参数。在这种情况下,问题就更大了:它会尝试将t&lt;void&gt; 解析和解释为基类类型,并认为您要调用基类的默认构造函数。这当然会失败。

    如果你能忍受它,你可以解决它

    struct T { 
        template<class U> T(identity<U>);
    };
    
    struct U {
        U() : t(identity<void>()) {}
        T t;
    };
    

    给定identity,就像它在 boost 中定义的那样

    template<typename T> struct identity { typedef T type; };
    

    在 C++20 中,您可以使用 std::type_identity 作为标识类型。

    【讨论】:

    • @litb:你知道他们是否有任何理由不让你明确地调用 T::T()?
    • @KeithM 您可以指定让您感到困惑的地方,然后我们一定能够澄清您对注释的理解。也许这就足够了:如果你使用T(),那么T 是结构T 的名称,而不是构造函数的名称(它没有)。因此,如果您说T&lt;...&gt;(),那么无论传递什么参数,都不会传递给构造函数,而是会尝试传递给根本不是模板的结构。
    • 这里只是一个单词沙拉。 explicit template argument listfunction template nameconversion member function templatesconstructor member function templates。我几乎不懂那些抽象的术语(对不起,无法抗拒双关语)。再次阅读您的新评论和段落后,我可能会理解(尽管我仍然不知道术语)。我认为这是说: t&lt;void&gt;() 不起作用,因为模板词缀总是在类型名称或函数名称之后,而t 两者都不是。那正确吗? (但为什么不改变标准以允许它呢?)
    • @KeithM 我已经为注释添加了解释。
    • @KeithM 至于原因,我不知道,但可以猜到他们没有找到令人信服的用例。也许您可以为此创建一个新问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 2011-09-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多