如何防止非专用模板实例化?

发布于 2024-11-30 03:51:00 字数 781 浏览 1 评论 0原文

我有一个模板化的class(称之为Foo),它有几个专业化。如果有人尝试使用 Foo 的非专业版本,我希望编译失败。

这是我实际拥有的:

template <typename Type>
class Foo
{
  Foo() { cannot_instantiate_an_unspecialized_Foo(); }

  // This method is NEVER defined to prevent linking.
  // Its name was chosen to provide a clear explanation why the compilation failed.
  void cannot_instantiate_an_unspecialized_Foo();
};

template <>
class Foo<int>
{    };

template <>
class Foo<double>
{    };

所以:

int main()
{
  Foo<int> foo;
}

可以工作,而:

int main()
{
  Foo<char> foo;
}

不能。

显然,编译器链仅在链接过程发生时才会抱怨。但有没有办法让它之前抱怨呢?

我可以使用boost

I have a templated class (call it Foo) which has several specializations. I would like the compilation to fail if someone tries to use an unspecialized version of Foo.

Here is what I actually have:

template <typename Type>
class Foo
{
  Foo() { cannot_instantiate_an_unspecialized_Foo(); }

  // This method is NEVER defined to prevent linking.
  // Its name was chosen to provide a clear explanation why the compilation failed.
  void cannot_instantiate_an_unspecialized_Foo();
};

template <>
class Foo<int>
{    };

template <>
class Foo<double>
{    };

So that:

int main()
{
  Foo<int> foo;
}

Works while:

int main()
{
  Foo<char> foo;
}

Does not.

Obviously, the compiler chain only complains when the linking process takes place. But is there a way to make it complain before ?

I can use boost.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

江湖彼岸 2024-12-07 03:51:00

只是不要定义类:

template <typename Type>
class Foo;

template <>
class Foo<int> { };

int main(int argc, char *argv[]) 
{
    Foo<int> f; // Fine, Foo<int> exists
    Foo<char> fc; // Error, incomplete type
    return 0;
}

为什么这有效?只是因为没有任何通用模板。声明了,是的,但没有定义。

Just don't define the class:

template <typename Type>
class Foo;

template <>
class Foo<int> { };

int main(int argc, char *argv[]) 
{
    Foo<int> f; // Fine, Foo<int> exists
    Foo<char> fc; // Error, incomplete type
    return 0;
}

Why does this work? Simply because there isn't any generic template. Declared, yes, but not defined.

玉环 2024-12-07 03:51:00

您可以简单地不定义基本情况:

template <typename> class Foo;             // no definition!

template <> class Foo<int> { /* ... */ };  // Foo<int> is OK

You can simply not define the base case:

template <typename> class Foo;             // no definition!

template <> class Foo<int> { /* ... */ };  // Foo<int> is OK
土豪 2024-12-07 03:51:00

C++0x 的一个技巧(也可用于 C++03 static_assert 模拟,但错误消息并不一定比未定义主模板更好):

template<typename T>
struct dependent_false: std::false_type {};

template<typename Type>
struct Foo {
    static_assert( dependent_false<Type>::value
                 , "Only specializations of Foo may be used" );
};

断言仅在以下情况下触发 : code>Foo 使用主模板进行实例化。使用 static_assert( false, ... ) 将始终触发断言。

A trick for C++0x (also available with a C++03 static_assert emulation, but the error message isn't necessarily better than leaving the primary template undefined):

template<typename T>
struct dependent_false: std::false_type {};

template<typename Type>
struct Foo {
    static_assert( dependent_false<Type>::value
                 , "Only specializations of Foo may be used" );
};

The assertion will only trigger when Foo is instantiated with the primary template. Using static_assert( false, ... ) would trigger the assertion all the time.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文