【问题标题】:C++ member overloads based on existence of template member基于模板成员存在的 C++ 成员重载
【发布时间】:2018-05-22 20:06:39
【问题描述】:

我从一些 SFINAE 开始,但我无法完全掌握一些我想使用它的情况。

例如,如果我有一个基于模板的类,它应该根据模板参数具有不同的函数实现,即

template <typename T>
class cExampleClass
{
     /// Function enabled when "cExampleClass::member" exists
     auto overloadedFunction() -> decltype((std::declval<t>().member()),T::some_dependant_type())
     {
           // Do some stuff and use cExampleClass::member
     }

     /// Function enabled when "cExampleClass::member" does not exist
     auto overloadedFunction() -> T::some_dependant_type()
     {
           // Do some different stuff
     }
};

最好将函数调用为

object.overloadedFunction();

我的编译器抛出

错误:‘class cARD’没有名为‘member’的成员

在 decltype 行上(即使未定义回退函数)。这似乎与here 的答案相矛盾,那么定义尾随返回类型的正确方法是什么?

此外,该函数显然不能重载。有没有简单的方法来定义一个回退函数?

【问题讨论】:

    标签: c++ templates sfinae


    【解决方案1】:

    你有一个硬错误,因为你的方法不是模板,把它改成:

    template <typename U>
    class cExampleClass
    {
         /// Function enabled when "cExampleClass::member" exists
         template <typename T = U>
         auto overloadedFunction()
         -> decltype((std::declval<T>().member()),T::some_dependant_type())
         {
               // Do some stuff and use cExampleClass::member
         }
    
         /// Function enabled when "cExampleClass::member" does not exist
         template <typename T = U>
         auto overloadedFunction() -> decltype(T::some_dependant_type())
         {
               // Do some different stuff
         }
    };
    

    但是您遇到了问题,因为该方法对于匹配这两个条件的类型会模棱两可。

    添加标签以对重载进行排序是可能的:

    template <std::size_t I>
    struct overload_tag : overload_tag<I - 1> {};
    
    template <>
    struct overload_tag<0> {};
    

    然后

    template <typename U>
    class cExampleClass
    {
    private:
         /// Function enabled when "cExampleClass::member" exists
         /// Preferred function
         template <typename T = U>
         auto overloadedFunction(overload_tag<1>)
         -> decltype((std::declval<T>().member()),T::some_dependant_type())
         {
               // Do some stuff and use cExampleClass::member
         }
    
         /// Function enabled when "cExampleClass::member" does not exist
         template <typename T = U>
         auto overloadedFunction(overload_tag<0>) -> decltype(T::some_dependant_type())
         {
               // Do some different stuff
         }
    public:
         template <typename T = U>
         auto overloadedFunction() -> decltype(overloadedFunction(overload_tag<1>{}))
         {
              return overloadedFunction(overload_tag<1>{});
         }
    };
    

    【讨论】:

    • 谢谢。尤其是标签。
    猜你喜欢
    • 1970-01-01
    • 2018-06-08
    • 1970-01-01
    • 2020-10-10
    • 1970-01-01
    • 2013-09-22
    • 1970-01-01
    • 1970-01-01
    • 2012-09-25
    相关资源
    最近更新 更多