模板函数参数显式类型声明

时间:2018-08-23 22:43:47

标签: c++ c++11 templates constexpr sfinae

我有一个运算符重载列表,我发现它们没有按照我想要的方式工作。我将有问题的代码简化为几行来模拟问题。我有几个模板类型别名来帮助进行时间决策,一个模板函数(工作代码中的一个运算符,这里只是一个通用函数),以及一个名为var的类,它带有两个模板参数,一个unsigned intbooltrue =已知变量,false =未知变量,仅提及此点,以使以下代码片段中的命名约定有意义)。这是代码。

template<typename T>
using is_known = typename std::is_same<T, const var<T::ID, true> >::type;

template<typename T>
using is_unknown = typename std::conditional<is_known<T>::value, std::false_type, std::true_type>::type;

template<typename T>
using UK_if_UK = typename std::enable_if<is_unknown<T>::value, T>::type;

template<typename unknown_check_LHS, typename unknown_check_RHS>
constexpr const two_param_type<UK_if_UK<unknown_check_LHS>, UK_if_UK<unknown_check_RHS> > func(const unknown_check_LHS& lhs, const unknown_check_RHS& rhs)
{
    return two_param_type<unknown_check_LHS, unknown_check_RHS>
    (//generic construction goes here, unimportant...);
}

int main()
{
    constexpr const var<0u,true> firstvar(123);
    constexpr const var<1u,true> secondvar(456);

    func(firstvar,secondvar);
    func<std::decltype(firstvar),std::decltype(secondvar)>(firstvar,secondvar);
}

func()的两次调用对我来说似乎是相同的,而且它们都应该失败(在工作代码中,一旦此功能SFINAE失效,还有其他选择)。但是,只有第二次调用(我在其中明确声明了类型)才编译器抛出错误。它完美地编译了对func()的首次调用,甚至更糟的是,即使返回类型中的类型别名应SFINAE该函数退出重载,它仍会操作并返回“已知”类型(var<(some unsigned),true>)。解析度。我正在使用运算符,因此明确声明类型不是我的选择。但是,更重要的是,我想知道为什么该功能没有得到完善。任何帮助,将不胜感激。谢谢。

注意:具体错误是:

error: no matching function for call to 'func(const var<0u, true>&, const var<1u, true>&)'

我还测试了is_knownis_unknownUK_if_UK的正常工作,因此不需要测试它们。谢谢。

1 个答案:

答案 0 :(得分:1)

  

对func的两次调用似乎与我相同

错。

它们是不同的。

这是一个常数问题。

使用

constexpr const var<0u,true> firstvar(123);
constexpr const var<1u,true> secondvar(456);

func()的签名如下

template<typename unknown_check_LHS, typename unknown_check_RHS>
constexpr /* ... */ func (const unknown_check_LHS & lhs,
                          const unknown_check_RHS & rhs)

通话

func(firstvar,secondvar);

unknown_check_LHSunknown_check_RHS类型分别被检测为var<0u, true>var<1u, true>

请注意:var<0u, true>var<1u, true>,而不是const var<0u, true>const var<1u, true>

相反,将类型说明如下

func<decltype(firstvar), decltype(secondvar)>(firstvar,secondvar);

(并且请使用decltype(),而不是std::decltype()),unknown_check_LHSunknown_check_RHS分别表示为const var<0u, true>const var<1u, true>

观察到现在类型为恒定

观察is_know的定义

template<typename T>
using is_known = typename std::is_same<T, const var<T::ID, true> >::type;

它将类型T与常量类型进行比较。

因此,在第一种情况下(模板类型不是恒定的),is_known为假;在第二种情况下(具有恒定的模板类型),是真的。