如何在不导致实例化的情况下获取函数模板的签名?

时间:2017-11-20 21:04:48

标签: c++ c++11 decltype

我想知道是否有特定规则指明此代码是否应该失败:

struct Foo {
    template<typename T>
    int bar() {
        static_assert(!std::is_same<T, float>::value, "Don't send floats please.");
        return 0;
    }

    int baz() { return 0; }
};

int main() {
    using function_type = decltype(&Foo::bar<float>);

    function_type func = &Foo::baz;
    (void) func;
}

此示例在GCC and Clang上均失败。为什么它必须失败?看起来采用函数的类型不应该导致实例化,甚至更少触发静态断言。为什么会失败?还有另一种方法来获取函数模板的签名而不会导致它的实体实例化吗?

我的用例是反映功能模板的签名。我的代码的用户使用一些参数调用我的代码。然后,我将这些参数与函数的模板参数进行匹配,以获取它的签名,然后使用签名来提取尚未发送的参数类型。

当功能通过转发参考时,没有问题。但是,如果该函数按值接收参数,我应该发送std::decay_t<Arg>作为模板参数,以免在函数体中导致编译错误。但是我无法知道我是否通过参考值接收签名的函数而没有进一步的反射功能。如果我能够获得功能模板的签名而不引起它的实例化,那将是完美的。

1 个答案:

答案 0 :(得分:0)

在您的情况下,它强制调用显式实例化,仅当将模板定义放在同一编译单元中时才会发生。如果您可以将c ++ 11功能与extern template一起使用,从而可以将模板声明和定义拆分为不同的* .h和* .hpp文件(例如),则可以使用不带实例化的声明(和{{1} })。请参阅参考:https://en.cppreference.com/w/cpp/language/function_template

  

显式实例化声明(一个extern模板)可以防止隐式实例化:否则会导致隐式实例化的代码必须使用程序其他地方提供的显式实例化定义。

如果要使用特殊static_assert特殊声明,则可以使用以下代码:

float

P.S。您可以解释或添加用例示例(客户端代码)吗?可能还有另一种解决方案...