我是否可以使用decltype(或类似的东西)进行显式模板实例化而无需签名重复?

时间:2015-02-05 23:20:29

标签: c++ templates c++11 instantiation decltype

我想实例化

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 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>);

但由于某种原因,这不起作用。为什么?

4 个答案:

答案 0 :(得分:6)

它确实有效,但语法不同:

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

decltype为您提供类型,但显式实例化需要声明,这是一个后跟名称的类型。

尝试使用GCC 4.9.1;它按预期工作,即使使用-pedantic标志,也可以在没有任何警告的情况下进行编译。

答案 1 :(得分:4)

它实际上比@ 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>;

意愿。

答案 2 :(得分:1)

不,因为超载

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);

如果您不想输入所有内容,那么康拉德建议使用宏是一种方法。

答案 3 :(得分:0)

我认为这对宏来说是一个很好的合法用法:

#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