【问题标题】:enable_if on explicit templated cast operator gives "invalid static_cast"enable_if 在显式模板化转换运算符上给出“无效的静态转换”
【发布时间】:2014-12-12 02:47:09
【问题描述】:

我正在尝试做一个模板化的显式转换运算符。我发现从符号上讲,您实际上可以将具有类型特征和 std::enable_if 的表达式放在运算符的“名称”槽中。但是以下测试没有给出预期的行为:

#include <iostream>
#include <type_traits>

class WillCast {
public:
    explicit operator int () {
       return 1020;
    }
};

class WontCast {
public:
    template <typename T>
    typename std::enable_if<
        std::is_same<T, int>::value, int
    >::type toInteger()
    {
       return 1324;
    }

    template <typename T>
    explicit operator typename std::enable_if<
        std::is_same<T, int>::value, int
    >::type ()
    {
       return 304;
    }
};

int main() {
    std::cout << static_cast<int>(WillCast{}) << "\n";   // ok
    std::cout << WontCast{}.toInteger<int>() << "\n";    // ok
    /* std::cout << static_cast<int>(WontCast{}); */     // error 
};

从 gcc 4.8.2 返回的错误是:

test.cpp: In function ‘int main()’:
test.cpp:27:45: error: invalid static_cast from type ‘WontCast’ to type ‘int’
    std::cout << static_cast<int>(WontCast{});

如果我尝试做的事情是不可能的,我不会感到惊讶。但它似乎认为语法没问题,只是在WontCast::toInteger()WillCast::operator int() 看到的“附近”行为之间的行为似乎不一致。

(这是一个简化的例子,当然我想要的enable_if 更棘手。)


更新 - “Sidebar Intelligence(tm)”抛出了How can I use std::enable_if in a conversion operator?,我没有通过“BeforeYouAsked Intelligence(tm)”找到它。我会看看它是否有帮助。好吧,那里使用的解决方案似乎并不适用,因为 WontCast 不是模板类。所以这里没有帮助。

【问题讨论】:

  • @remyabel 这确实适用于该特定情况,但如果该特定情况是我正在寻找的,我可以使用 WillCast 并说“int”。我正在寻找能够进行模式匹配并产生大量强制转换运算符的东西......但仅限于正确的情况。
  • this 怎么样?它使用与您问题中的链接相同的技巧。
  • @HostileFork 很酷的问题 - 在我开始尝试之前我什至没有意识到这是可能的。

标签: c++ casting operator-overloading sfinae enable-if


【解决方案1】:

如果您将 enable_if 部分移到模板中,则可以:

template <typename T,
          typename = typename std::enable_if<std::is_same<T, int>::value>::type
          >
explicit operator T()
{
    return 304;
}

鉴于:

int i = static_cast<int>(WontCast{}); // ok
double d = static_cast<double>(WontCast{}); // invalid static_cast

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-05
    • 2011-12-06
    • 1970-01-01
    • 2020-10-14
    • 2014-01-21
    • 1970-01-01
    • 2021-01-01
    相关资源
    最近更新 更多