我可以在不重复签名的情况下实例化模板吗?

Can I instantiate a template without repeating its signature?

我想实例化一些具有长签名的函数:

template<typename T> void foo(
    T& t,
    SomeType some_parameter,
    AnotherType another_parameter,
    EtcType yet_another_parameter,
    AsYouCanTell this_is_a_very_long_signature);

实例化 foo 的直接方法是:

template void foo<int>(
    int& t,
    SomeType some_parameter,
    AnotherType another_parameter,
    EtcType yet_another_parameter,
    AsYouCanTell this_is_a_very_long_signature);

但这是长签名的重复。如果我想要 5 种不同类型的特定实例化怎么办 - 我是否将其复制 5 次?没有意义...

我在想也许我可以写

template decltype(foo<int>);

但出于某种原因,这不起作用。我能以某种方式让它工作吗?

我认为这是一个很好的、合法的宏用法:

#define INSTANTIATE_FOO(type) \
    template void foo<type>(type& t, \
                  SomeType some_parameter, \
                  AnotherType another_parameter, \
                  EtcType yet_another_parameter, \
                  AsYouCanTell this_is_a_very_long_signature);

INSTANTIATE_FOO(int)
INSTANTIATE_FOO(float)
INSTANTIATE_FOO(my_little_dragon)

#undef INSTANTIATE_FOO

否,因为超载

template<typename T> void foo(T& t,
                     SomeType some_parameter,
                     AnotherType another_parameter,
                     EtcType yet_another_parameter,
                     AsYouCanTell this_is_a_very_long_signature);
template<template T> void foo(T& t); //completely unrelated function
template<template T> void foo(char); //another completely unrelated function

现在想象一下,显式实例化第一个所需的最少信息是什么?嗯,你需要完整的签名来消除歧义,所以

explicit int foo(int&, SomeType, AnotherType, EtcType, AsYouCanTell)

是理论上的最小信息量。所以 C++ 要求的开销实际上很少:

template void foo<int>(int& t, SomeType, AnotherType, EtcType, AsYouCanTell);

如果您不想输入所有这些内容,那么康拉德建议的宏就是您的选择。

您确实可以在不重复其签名的情况下实例化您的函数 - 但语法略有不同:

template
decltype(foo<int>) foo<int>;

decltype 给你一个 type 但显式实例化需要一个 declaration 这是一个类型后跟一个名称。

尝试使用 GCC 4.9.1;它按预期工作并且编译时没有任何警告,即使使用 -pedantic 标志也是如此。

实际上比@5gon12eder 建议的还要简单:

template decltype(foo<int>) foo;

但是,是的,正如他所说 - decltype() 仅提供类型,而签名并不是真正的类型。

编辑: 当模板有值参数而不仅仅是类型时,这不起作用,所以如果我们有

template <typename T, unsigned Val> bar(T t);

然后

template decltype(bar<int, 1>) bar;

不会编译,而

template decltype(bar<int, 1>) bar<int, 1>;

会。