我可以在不重复签名的情况下实例化模板吗?
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>;
会。
我想实例化一些具有长签名的函数:
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>;
会。